pepr 0.55.6 → 1.0.0-nightly.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/init/templates.d.ts +0 -1
- package/dist/cli/init/templates.d.ts.map +1 -1
- package/dist/cli.js +86 -125
- package/dist/controller.js +1 -1
- package/dist/lib/assets/ignoredNamespaces.d.ts +2 -0
- package/dist/lib/assets/ignoredNamespaces.d.ts.map +1 -1
- package/dist/lib/assets/webhooks.d.ts +2 -2
- package/dist/lib/assets/webhooks.d.ts.map +1 -1
- package/dist/lib/assets/yaml/overridesFile.d.ts.map +1 -1
- package/dist/lib/controller/index.d.ts.map +1 -1
- package/dist/lib/core/capability.d.ts.map +1 -1
- package/dist/lib/core/module.d.ts +9 -7
- package/dist/lib/core/module.d.ts.map +1 -1
- package/dist/lib/processors/mutate-processor.d.ts.map +1 -1
- package/dist/lib/processors/validate-processor.d.ts.map +1 -1
- package/dist/lib.js +59 -50
- package/dist/lib.js.map +2 -2
- package/package.json +7 -8
- package/src/lib/assets/ignoredNamespaces.ts +9 -0
- package/src/lib/assets/webhooks.ts +11 -15
- package/src/lib/assets/yaml/overridesFile.ts +117 -116
- package/src/lib/controller/index.ts +14 -5
- package/src/lib/core/capability.ts +3 -0
- package/src/lib/core/module.ts +53 -48
- package/src/lib/processors/mutate-processor.ts +2 -6
- package/src/lib/processors/validate-processor.ts +2 -11
- package/src/lib/processors/watch-processor.ts +1 -1
package/dist/lib.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/lib.ts", "../src/lib/core/capability.ts", "../src/lib/telemetry/logger.ts", "../src/lib/core/envChecks.ts", "../src/lib/core/storage.ts", "../src/lib/core/schedule.ts", "../src/lib/finalizer.ts", "../src/lib/core/module.ts", "../src/lib/controller/index.ts", "../src/lib/telemetry/metrics.ts", "../src/lib/processors/mutate-processor.ts", "../src/lib/telemetry/timeUtils.ts", "../src/lib/telemetry/webhookTimeouts.ts", "../src/lib/filter/adjudicators/admissionRequest.ts", "../src/lib/filter/adjudicators/binding.ts", "../src/lib/filter/adjudicators/kubernetesObject.ts", "../src/lib/filter/adjudicators/mismatch.ts", "../src/lib/filter/adjudicators/postCollection.ts", "../src/lib/filter/adjudication.ts", "../src/lib/filter/filter.ts", "../src/lib/mutate-request.ts", "../src/lib/utils.ts", "../src/cli/init/enums.ts", "../src/lib/assets/ignoredNamespaces.ts", "../src/lib/processors/decode-utils.ts", "../src/lib/validate-request.ts", "../src/lib/processors/validate-processor.ts", "../src/lib/controller/store.ts", "../src/lib/k8s.ts", "../src/lib/controller/storeCache.ts", "../src/lib/controller/migrateStore.ts", "../src/lib/controller/index.util.ts", "../src/lib/features/FeatureFlags.ts", "../src/lib/features/store.ts", "../src/lib/errors.ts", "../src/lib/processors/watch-processor.ts", "../src/lib/core/queue.ts", "../src/lib/controller/createHooks.ts", "../src/sdk/sdk.ts"],
|
|
4
|
-
"sourcesContent": ["import { K8s, RegisterKind, kind as a, fetch, fetchStatus, kind } from \"kubernetes-fluent-client\";\nimport * as R from \"ramda\";\n\nimport { Capability } from \"./lib/core/capability\";\nimport Log from \"./lib/telemetry/logger\";\nimport { PeprModule } from \"./lib/core/module\";\nimport { PeprMutateRequest } from \"./lib/mutate-request\";\nimport * as PeprUtils from \"./lib/utils\";\nimport { PeprValidateRequest } from \"./lib/validate-request\";\nimport * as sdk from \"./sdk/sdk\";\nimport { metricsCollector } from \"./lib/telemetry/metrics\";\n\nexport {\n metricsCollector,\n Capability,\n K8s,\n Log,\n PeprModule,\n PeprMutateRequest,\n PeprUtils,\n PeprValidateRequest,\n R,\n RegisterKind,\n a,\n fetch,\n fetchStatus,\n kind,\n sdk,\n};\n", "// SPDX-License-Identifier: Apache-2.0\n// SPDX-FileCopyrightText: 2023-Present The Pepr Authors\n\nimport { GenericClass, GroupVersionKind, modelToGroupVersionKind } from \"kubernetes-fluent-client\";\nimport { pickBy } from \"ramda\";\nimport Log from \"../telemetry/logger\";\nimport { isBuildMode, isDevMode, isWatchMode } from \"./envChecks\";\nimport { PeprStore, Storage } from \"./storage\";\nimport { OnSchedule, Schedule } from \"./schedule\";\nimport { Event } from \"../enums\";\nimport {\n Binding,\n BindingFilter,\n BindingWithName,\n CapabilityCfg,\n CapabilityExport,\n MutateAction,\n MutateActionChain,\n ValidateAction,\n ValidateActionChain,\n WatchLogAction,\n FinalizeAction,\n FinalizeActionChain,\n WhenSelector,\n} from \"../types\";\nimport { addFinalizer } from \"../finalizer\";\n\nconst registerAdmission = isBuildMode() || !isWatchMode();\nconst registerWatch = isBuildMode() || isWatchMode() || isDevMode();\n\n/**\n * A capability is a unit of functionality that can be registered with the Pepr runtime.\n */\nexport class Capability implements CapabilityExport {\n #name: string;\n #description: string;\n #namespaces?: string[] | undefined;\n #bindings: Binding[] = [];\n #store = new Storage();\n #scheduleStore = new Storage();\n #registered = false;\n #scheduleRegistered = false;\n hasSchedule: boolean;\n\n /**\n * Run code on a schedule with the capability.\n *\n * @param schedule The schedule to run the code on\n * @returns\n */\n OnSchedule: (schedule: Schedule) => void = (schedule: Schedule) => {\n const { name, every, unit, run, startTime, completions } = schedule;\n this.hasSchedule = true;\n\n if (process.env.PEPR_WATCH_MODE === \"true\" || process.env.PEPR_MODE === \"dev\") {\n // Only create/watch schedule store if necessary\n\n // Create a new schedule\n const newSchedule: Schedule = {\n name,\n every,\n unit,\n run,\n startTime,\n completions,\n };\n\n this.#scheduleStore.onReady(() => {\n new OnSchedule(newSchedule).setStore(this.#scheduleStore);\n });\n }\n };\n\n public getScheduleStore(): Storage {\n return this.#scheduleStore;\n }\n\n /**\n * Store is a key-value data store that can be used to persist data that should be shared\n * between requests. Each capability has its own store, and the data is persisted in Kubernetes\n * in the `pepr-system` namespace.\n *\n * Note: You should only access the store from within an action.\n */\n Store: PeprStore = {\n clear: this.#store.clear,\n getItem: this.#store.getItem,\n removeItem: this.#store.removeItem,\n removeItemAndWait: this.#store.removeItemAndWait,\n setItem: this.#store.setItem,\n subscribe: this.#store.subscribe,\n onReady: this.#store.onReady,\n setItemAndWait: this.#store.setItemAndWait,\n };\n\n /**\n * ScheduleStore is a key-value data store used to persist schedule data that should be shared\n * between intervals. Each Schedule shares store, and the data is persisted in Kubernetes\n * in the `pepr-system` namespace.\n *\n * Note: There is no direct access to schedule store\n */\n ScheduleStore: PeprStore = {\n clear: this.#scheduleStore.clear,\n getItem: this.#scheduleStore.getItem,\n removeItemAndWait: this.#scheduleStore.removeItemAndWait,\n removeItem: this.#scheduleStore.removeItem,\n setItemAndWait: this.#scheduleStore.setItemAndWait,\n setItem: this.#scheduleStore.setItem,\n subscribe: this.#scheduleStore.subscribe,\n onReady: this.#scheduleStore.onReady,\n };\n\n get bindings(): Binding[] {\n return this.#bindings;\n }\n\n get name(): string {\n return this.#name;\n }\n\n get description(): string {\n return this.#description;\n }\n\n get namespaces(): string[] {\n return this.#namespaces || [];\n }\n\n constructor(cfg: CapabilityCfg) {\n this.#name = cfg.name;\n this.#description = cfg.description;\n this.#namespaces = cfg.namespaces;\n this.hasSchedule = false;\n\n Log.debug(`Capability ${this.#name} registered`);\n Log.debug(cfg);\n }\n\n /**\n * Register the store with the capability. This is called automatically by the Pepr controller.\n */\n registerScheduleStore = (): Storage => {\n Log.debug(`Registering schedule store for ${this.#name}`);\n\n if (this.#scheduleRegistered) {\n throw new Error(`Schedule store already registered for ${this.#name}`);\n }\n\n this.#scheduleRegistered = true;\n\n // Pass back any ready callback to the controller\n return this.#scheduleStore;\n };\n\n /**\n * Register the store with the capability. This is called automatically by the Pepr controller.\n *\n * @param store\n */\n registerStore = (): Storage => {\n Log.debug(`Registering store for ${this.#name}`);\n\n if (this.#registered) {\n throw new Error(`Store already registered for ${this.#name}`);\n }\n\n this.#registered = true;\n\n // Pass back any ready callback to the controller\n return this.#store;\n };\n\n /**\n * The When method is used to register a action to be executed when a Kubernetes resource is\n * processed by Pepr. The action will be executed if the resource matches the specified kind and any\n * filters that are applied.\n *\n * @param model the KubernetesObject model to match\n * @param kind if using a custom KubernetesObject not available in `a.*`, specify the GroupVersionKind\n * @returns\n */\n When = <T extends GenericClass>(model: T, kind?: GroupVersionKind): WhenSelector<T> => {\n const matchedKind = modelToGroupVersionKind(model.name);\n\n // If the kind is not specified and the model is not a KubernetesObject, throw an error\n if (!matchedKind && !kind) {\n throw new Error(`Kind not specified for ${model.name}`);\n }\n\n const binding: Binding = {\n model,\n // If the kind is not specified, use the matched kind from the model\n kind: kind || matchedKind,\n event: Event.ANY,\n filters: {\n name: \"\",\n namespaces: [],\n regexNamespaces: [],\n regexName: \"\",\n labels: {},\n annotations: {},\n deletionTimestamp: false,\n },\n };\n\n const bindings = this.#bindings;\n const prefix = `${this.#name}: ${model.name}`;\n const commonChain = {\n WithLabel,\n WithAnnotation,\n WithDeletionTimestamp,\n Mutate,\n Validate,\n Watch,\n Reconcile,\n Alias,\n };\n\n type CommonChainType = typeof commonChain;\n type ExtendedCommonChainType = CommonChainType & {\n Alias: (alias: string) => CommonChainType;\n InNamespace: (...namespaces: string[]) => BindingWithName<T>;\n InNamespaceRegex: (...namespaces: RegExp[]) => BindingWithName<T>;\n WithName: (name: string) => BindingFilter<T>;\n WithNameRegex: (regexName: RegExp) => BindingFilter<T>;\n WithDeletionTimestamp: () => BindingFilter<T>;\n };\n\n const isNotEmpty = (value: object): boolean => Object.keys(value).length > 0;\n const log = (message: string, cbString: string): void => {\n const filteredObj = pickBy(isNotEmpty, binding.filters);\n\n Log.info({ prefix }, `${message} configured for ${binding.event}`);\n Log.info({ prefix }, JSON.stringify(filteredObj));\n Log.debug({ prefix }, cbString);\n };\n\n function Validate(validateCallback: ValidateAction<T>): ValidateActionChain<T> {\n if (registerAdmission) {\n log(\"Validate Action\", validateCallback.toString());\n\n // Create the child logger\n const aliasLogger = Log.child({ alias: binding.alias || \"no alias provided\" });\n\n // Push the binding to the list of bindings for this capability as a new BindingAction\n // with the callback function to preserve\n bindings.push({\n ...binding,\n isValidate: true,\n validateCallback: async (req, logger = aliasLogger) => {\n if (binding.alias) {\n Log.info(`Executing validate action with alias: ${binding.alias}`);\n }\n return await validateCallback(req, logger);\n },\n });\n }\n\n return { Watch, Reconcile };\n }\n\n function Mutate(mutateCallback: MutateAction<T>): MutateActionChain<T> {\n if (registerAdmission) {\n log(\"Mutate Action\", mutateCallback.toString());\n\n // Create the child logger\n const aliasLogger = Log.child({ alias: binding.alias || \"no alias provided\" });\n\n // Push the binding to the list of bindings for this capability as a new BindingAction\n // with the callback function to preserve\n bindings.push({\n ...binding,\n isMutate: true,\n mutateCallback: async (req, logger = aliasLogger) => {\n if (binding.alias) {\n Log.info(`Executing mutation action with alias: ${binding.alias}`);\n }\n await mutateCallback(req, logger);\n },\n });\n }\n\n // Now only allow adding actions to the same binding\n return { Watch, Validate, Reconcile };\n }\n\n function Watch(watchCallback: WatchLogAction<T>): FinalizeActionChain<T> {\n if (registerWatch) {\n log(\"Watch Action\", watchCallback.toString());\n\n // Create the child logger and cast it to the expected type\n const aliasLogger = Log.child({\n alias: binding.alias || \"no alias provided\",\n }) as typeof Log;\n\n // Push the binding to the list of bindings for this capability as a new BindingAction\n // with the callback function to preserve\n bindings.push({\n ...binding,\n isWatch: true,\n watchCallback: async (update, phase, logger = aliasLogger) => {\n if (binding.alias) {\n Log.info(`Executing watch action with alias: ${binding.alias}`);\n }\n await watchCallback(update, phase, logger);\n },\n });\n }\n return { Finalize };\n }\n\n function Reconcile(reconcileCallback: WatchLogAction<T>): FinalizeActionChain<T> {\n if (registerWatch) {\n log(\"Reconcile Action\", reconcileCallback.toString());\n\n // Create the child logger and cast it to the expected type\n const aliasLogger = Log.child({\n alias: binding.alias || \"no alias provided\",\n }) as typeof Log;\n\n // Push the binding to the list of bindings for this capability as a new BindingAction\n // with the callback function to preserve\n bindings.push({\n ...binding,\n isWatch: true,\n isQueue: true,\n watchCallback: async (update, phase, logger = aliasLogger) => {\n if (binding.alias) {\n Log.info(`Executing reconcile action with alias: ${binding.alias}`);\n }\n await reconcileCallback(update, phase, logger);\n },\n });\n }\n return { Finalize };\n }\n\n function Finalize(finalizeCallback: FinalizeAction<T>): void {\n log(\"Finalize Action\", finalizeCallback.toString());\n\n // Create the child logger and cast it to the expected type\n const aliasLogger = Log.child({ alias: binding.alias || \"no alias provided\" }) as typeof Log;\n\n // Add binding to inject Pepr finalizer during admission (Mutate)\n if (registerAdmission) {\n const mutateBinding = {\n ...binding,\n isMutate: true,\n isFinalize: true,\n event: Event.ANY,\n mutateCallback: addFinalizer,\n };\n bindings.push(mutateBinding);\n }\n\n // Add binding to process finalizer callback / remove Pepr finalizer (Watch)\n if (registerWatch) {\n const watchBinding = {\n ...binding,\n isWatch: true,\n isFinalize: true,\n event: Event.UPDATE,\n finalizeCallback: async (\n update: InstanceType<T>,\n logger = aliasLogger,\n ): Promise<boolean | void> => {\n if (binding.alias) {\n Log.info(`Executing finalize action with alias: ${binding.alias}`);\n }\n return await finalizeCallback(update, logger);\n },\n };\n bindings.push(watchBinding);\n }\n }\n\n function InNamespace(...namespaces: string[]): BindingWithName<T> {\n Log.debug({ prefix }, `Add namespaces filter ${namespaces}`);\n binding.filters.namespaces.push(...namespaces);\n return { ...commonChain, WithName, WithNameRegex };\n }\n\n function InNamespaceRegex(...namespaces: RegExp[]): BindingWithName<T> {\n Log.debug({ prefix }, `Add regex namespaces filter ${namespaces}`);\n binding.filters.regexNamespaces.push(...namespaces.map(regex => regex.source));\n return { ...commonChain, WithName, WithNameRegex };\n }\n\n function WithDeletionTimestamp(): BindingFilter<T> {\n Log.debug({ prefix }, \"Add deletionTimestamp filter\");\n binding.filters.deletionTimestamp = true;\n return commonChain;\n }\n\n function WithNameRegex(regexName: RegExp): BindingFilter<T> {\n Log.debug({ prefix }, `Add regex name filter ${regexName}`);\n binding.filters.regexName = regexName.source;\n return commonChain;\n }\n\n function WithName(name: string): BindingFilter<T> {\n Log.debug({ prefix }, `Add name filter ${name}`);\n binding.filters.name = name;\n return commonChain;\n }\n\n function WithLabel(key: string, value = \"\"): BindingFilter<T> {\n Log.debug({ prefix }, `Add label filter ${key}=${value}`);\n binding.filters.labels[key] = value;\n return commonChain;\n }\n\n function WithAnnotation(key: string, value = \"\"): BindingFilter<T> {\n Log.debug({ prefix }, `Add annotation filter ${key}=${value}`);\n binding.filters.annotations[key] = value;\n return commonChain;\n }\n\n function Alias(alias: string): CommonChainType {\n Log.debug({ prefix }, `Adding prefix alias ${alias}`);\n binding.alias = alias;\n return commonChain;\n }\n\n function bindEvent(event: Event): ExtendedCommonChainType {\n binding.event = event;\n return {\n ...commonChain,\n InNamespace,\n InNamespaceRegex,\n WithName,\n WithNameRegex,\n WithDeletionTimestamp,\n Alias,\n };\n }\n\n return {\n IsCreatedOrUpdated: () => bindEvent(Event.CREATE_OR_UPDATE),\n IsCreated: () => bindEvent(Event.CREATE),\n IsUpdated: () => bindEvent(Event.UPDATE),\n IsDeleted: () => bindEvent(Event.DELETE),\n };\n };\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// SPDX-FileCopyrightText: 2023-Present The Pepr Authors\n\nimport { Operation } from \"fast-json-patch\";\nimport { pino, stdTimeFunctions } from \"pino\";\nimport { Store } from \"../k8s\";\n\nconst isPrettyLog = process.env.PEPR_PRETTY_LOGS === \"true\";\nconst redactedValue = \"**redacted**\";\n\nconst pretty = {\n target: \"pino-pretty\",\n options: {\n colorize: true,\n },\n};\n\nconst transport = isPrettyLog ? pretty : undefined;\n// epochTime is the pino default\nconst pinoTimeFunction =\n process.env.PINO_TIME_STAMP === \"iso\"\n ? (): string => stdTimeFunctions.isoTime()\n : (): string => stdTimeFunctions.epochTime();\nconst Log = pino({\n transport,\n timestamp: pinoTimeFunction,\n});\n\nif (process.env.LOG_LEVEL) {\n Log.level = process.env.LOG_LEVEL;\n}\n\nexport function redactedStore(store: Store): Store {\n const redacted = process.env.PEPR_STORE_REDACT_VALUES === \"true\";\n return {\n ...store,\n data: Object.keys(store.data).reduce((acc: Record<string, string>, key: string) => {\n acc[key] = redacted ? redactedValue : store.data[key];\n return acc;\n }, {}),\n };\n}\n\nexport function redactedPatch(patch: Record<string, Operation> = {}): Record<string, Operation> {\n const redacted = process.env.PEPR_STORE_REDACT_VALUES === \"true\";\n\n if (!redacted) {\n return patch;\n }\n\n const redactedCache: Record<string, Operation> = {};\n\n Object.entries(patch).forEach(([key, operation]) => {\n const isRedacted = key.includes(\":\");\n const targetKey = isRedacted ? `${key.substring(0, key.lastIndexOf(\":\"))}:**redacted**` : key;\n\n const redactedOperation = isRedacted\n ? {\n ...operation,\n ...(Object.hasOwn(operation, \"value\") ? { value: redactedValue } : {}),\n }\n : operation;\n\n redactedCache[targetKey] = redactedOperation;\n });\n\n return redactedCache;\n}\n\nexport default Log;\n", "export const isWatchMode = (): boolean => process.env.PEPR_WATCH_MODE === \"true\";\n// Track if Pepr is running in build mode\n\nexport const isBuildMode = (): boolean => process.env.PEPR_MODE === \"build\";\n\nexport const isDevMode = (): boolean => process.env.PEPR_MODE === \"dev\";\n", "// SPDX-License-Identifier: Apache-2.0\n// SPDX-FileCopyrightText: 2023-Present The Pepr Authors\n\nimport { clone } from \"ramda\";\nimport pointer from \"json-pointer\";\nexport type DataOp = \"add\" | \"remove\";\nexport type DataStore = Record<string, string>;\nexport type DataSender = (op: DataOp, keys: string[], value?: string) => void;\ntype DataReceiver = (data: DataStore) => void;\nexport type Unsubscribe = () => void;\n\nconst MAX_WAIT_TIME = 15000;\nconst STORE_VERSION_PREFIX = \"v2\";\n\ninterface WaitRecord {\n timeout?: ReturnType<typeof setTimeout>;\n unsubscribe?: () => void;\n}\n\nexport function v2StoreKey(key: string): string {\n return `${STORE_VERSION_PREFIX}-${pointer.escape(key)}`;\n}\n\nexport function v2UnescapedStoreKey(key: string): string {\n return `${STORE_VERSION_PREFIX}-${key}`;\n}\n\nexport function stripV2Prefix(key: string): string {\n return key.replace(/^v2-/, \"\");\n}\nexport interface PeprStore {\n /**\n * Returns the current value associated with the given key, or null if the given key does not exist.\n */\n getItem(key: string): string | null;\n /**\n * Removes all key/value pairs, if there are any.\n */\n clear(): void;\n /**\n * Removes the key/value pair with the given key, if a key/value pair with the given key exists.\n */\n removeItem(key: string): void;\n /**\n * Sets the value of the pair identified by key to value, creating a new key/value pair if none existed for key previously.\n */\n setItem(key: string, value: string): void;\n\n /**\n * Subscribe to changes in the store. This API behaves similarly to the [Svelte Store API](https://vercel.com/docs/beginner-sveltekit/svelte-stores#using-the-store).\n *\n * @param listener - The callback to be invoked when the store changes.\n * @returns A function to unsubscribe from the listener.\n */\n subscribe(listener: DataReceiver): Unsubscribe;\n\n /**\n * Register a function to be called when the store is ready.\n */\n onReady(callback: DataReceiver): void;\n\n /**\n * Sets the value of the pair identified by key to value, creating a new key/value pair if none existed for key previously.\n * Resolves when the key/value show up in the store.\n */\n setItemAndWait(key: string, value: string): Promise<string>;\n\n /**\n * Remove the value of the key.\n * Resolves when the key does not show up in the store.\n */\n removeItemAndWait(key: string): Promise<string>;\n}\n\n/**\n * A key-value data store that can be used to persist data that should be shared across Pepr controllers and capabilities.\n *\n * The API is similar to the [Storage API](https://developer.mozilla.org/docs/Web/API/Storage)\n */\n\nexport class Storage implements PeprStore {\n #store: DataStore = {};\n #send!: DataSender;\n #subscribers: Record<number, DataReceiver> = {};\n #subscriberId = 0;\n #readyHandlers: DataReceiver[] = [];\n\n registerSender = (send: DataSender): void => {\n this.#send = send;\n };\n\n receive = (data: DataStore): void => {\n this.#store = data || {};\n\n this.#onReady();\n\n // Notify all subscribers\n for (const idx in this.#subscribers) {\n // Send a unique clone of the store to each subscriber\n this.#subscribers[idx](clone(this.#store));\n }\n };\n\n getItem = (key: string): string | null => {\n const result = this.#store[v2UnescapedStoreKey(key)] || null;\n if (result !== null && typeof result !== \"function\" && typeof result !== \"object\") {\n return result;\n }\n return null;\n };\n\n clear = (): void => {\n if (Object.keys(this.#store).length > 0) {\n this.#dispatchUpdate(\n \"remove\",\n Object.keys(this.#store).map(key => pointer.escape(key)),\n );\n }\n };\n\n removeItem = (key: string): void => {\n this.#dispatchUpdate(\"remove\", [v2StoreKey(key)]);\n };\n\n setItem = (key: string, value: string): void => {\n this.#dispatchUpdate(\"add\", [v2StoreKey(key)], value);\n };\n\n /**\n * Creates a promise and subscribes to the store, the promise resolves when\n * the key and value are seen in the store.\n *\n * @param key - The key to add into the store\n * @param value - The value of the key\n * @returns\n */\n setItemAndWait = (key: string, value: string): Promise<string> => {\n this.#dispatchUpdate(\"add\", [v2StoreKey(key)], value);\n const record: WaitRecord = {};\n\n return new Promise<string>((resolve, reject) => {\n // If promise has not resolved before MAX_WAIT_TIME reject\n record.timeout = setTimeout(() => {\n record.unsubscribe!();\n return reject(`MAX_WAIT_TIME elapsed: Key ${key} not seen in ${MAX_WAIT_TIME / 1000}s`);\n }, MAX_WAIT_TIME);\n\n record.unsubscribe = this.subscribe(data => {\n if (data[`${v2UnescapedStoreKey(key)}`] === value) {\n record.unsubscribe!();\n clearTimeout(record.timeout);\n resolve(\"ok\");\n }\n });\n });\n };\n\n /**\n * Creates a promise and subscribes to the store, the promise resolves when\n * the key is removed from the store.\n *\n * @param key - The key to add into the store\n * @returns\n */\n removeItemAndWait = (key: string): Promise<string> => {\n this.#dispatchUpdate(\"remove\", [v2StoreKey(key)]);\n const record: WaitRecord = {};\n return new Promise<string>((resolve, reject) => {\n // If promise has not resolved before MAX_WAIT_TIME reject\n record.timeout = setTimeout(() => {\n record.unsubscribe!();\n return reject(\n `MAX_WAIT_TIME elapsed: Key ${key} still seen after ${MAX_WAIT_TIME / 1000}s`,\n );\n }, MAX_WAIT_TIME);\n\n record.unsubscribe = this.subscribe(data => {\n if (!Object.hasOwn(data, `${v2UnescapedStoreKey(key)}`)) {\n record.unsubscribe!();\n clearTimeout(record.timeout);\n resolve(\"ok\");\n }\n });\n });\n };\n\n subscribe = (subscriber: DataReceiver): (() => void) => {\n const idx = this.#subscriberId++;\n this.#subscribers[idx] = subscriber;\n return () => this.unsubscribe(idx);\n };\n\n onReady = (callback: DataReceiver): void => {\n this.#readyHandlers.push(callback);\n };\n\n /**\n * Remove a subscriber from the list of subscribers.\n * @param idx - The index of the subscriber to remove.\n */\n unsubscribe = (idx: number): void => {\n delete this.#subscribers[idx];\n };\n\n #onReady = (): void => {\n // Notify all ready handlers with a clone of the store\n for (const handler of this.#readyHandlers) {\n handler(clone(this.#store));\n }\n\n // Make this a noop so that it can't be called again\n this.#onReady = (): void => {};\n };\n\n /**\n * Dispatch an update to the store and notify all subscribers.\n * @param op - The type of operation to perform.\n * @param keys - The keys to update.\n * @param [value] - The new value.\n */\n #dispatchUpdate = (op: DataOp, keys: string[], value?: string): void => {\n this.#send(op, keys, value);\n };\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// SPDX-FileCopyrightText: 2023-Present The Pepr Authors\n\nimport { PeprStore } from \"./storage\";\n\nexport type Unit = \"seconds\" | \"second\" | \"minute\" | \"minutes\" | \"hours\" | \"hour\";\n\nexport interface Schedule {\n /**\n * * The name of the store\n */\n name: string;\n /**\n * The value associated with a unit of time\n */\n every: number;\n /**\n * The unit of time\n */\n unit: Unit;\n /**\n * The code to run\n */\n run: () => void;\n /**\n * The start time of the schedule\n */\n startTime?: Date | undefined;\n\n /**\n * The number of times the schedule has run\n */\n completions?: number | undefined;\n /**\n * Tje intervalID to clear the interval\n */\n intervalID?: NodeJS.Timeout;\n}\n\nexport class OnSchedule implements Schedule {\n intervalId: NodeJS.Timeout | null = null;\n store: PeprStore | undefined;\n name!: string;\n completions?: number | undefined;\n every: number;\n unit: Unit;\n run!: () => void;\n startTime?: Date | undefined;\n duration: number | undefined;\n lastTimestamp: Date | undefined;\n\n constructor(schedule: Schedule) {\n this.name = schedule.name;\n this.run = schedule.run;\n this.every = schedule.every;\n this.unit = schedule.unit;\n this.startTime = schedule?.startTime;\n this.completions = schedule?.completions;\n }\n setStore(store: PeprStore): void {\n this.store = store;\n this.startInterval();\n }\n startInterval(): void {\n this.checkStore();\n this.getDuration();\n this.setupInterval();\n }\n /**\n * Checks the store for this schedule and sets the values if it exists\n * @returns\n */\n checkStore(): void {\n const result = this.store && this.store.getItem(this.name);\n if (result) {\n const storedSchedule = JSON.parse(result);\n this.completions = storedSchedule?.completions;\n this.startTime = storedSchedule?.startTime;\n this.lastTimestamp = storedSchedule?.lastTimestamp;\n }\n }\n\n /**\n * Saves the schedule to the store\n * @returns\n */\n saveToStore(): void {\n const schedule = {\n completions: this.completions,\n startTime: this.startTime,\n lastTimestamp: new Date(),\n name: this.name,\n };\n if (this.store) this.store.setItem(this.name, JSON.stringify(schedule));\n }\n\n /**\n * Gets the durations in milliseconds\n */\n getDuration(): void {\n switch (this.unit) {\n case \"seconds\":\n if (this.every < 10) throw new Error(\"10 Seconds in the smallest interval allowed\");\n this.duration = 1000 * this.every;\n break;\n case \"minutes\":\n case \"minute\":\n this.duration = 1000 * 60 * this.every;\n break;\n case \"hours\":\n case \"hour\":\n this.duration = 1000 * 60 * 60 * this.every;\n break;\n default:\n throw new Error(\"Invalid time unit\");\n }\n }\n\n /**\n * Sets up the interval\n */\n setupInterval(): void {\n const now = new Date();\n let delay: number | undefined;\n\n if (this.lastTimestamp && this.startTime) {\n this.startTime = undefined;\n }\n\n if (this.startTime) {\n delay = this.startTime.getTime() - now.getTime();\n } else if (this.lastTimestamp && this.duration) {\n const lastTimestamp = new Date(this.lastTimestamp);\n delay = this.duration - (now.getTime() - lastTimestamp.getTime());\n }\n\n if (delay === undefined || delay <= 0) {\n this.start();\n } else {\n setTimeout(() => {\n this.start();\n }, delay);\n }\n }\n\n /**\n * Starts the interval\n */\n start(): void {\n this.intervalId = setInterval(() => {\n if (this.completions === 0) {\n this.stop();\n return;\n } else {\n this.run();\n\n if (this.completions && this.completions !== 0) {\n this.completions -= 1;\n }\n this.saveToStore();\n }\n }, this.duration);\n }\n\n /**\n * Stops the interval\n */\n stop(): void {\n if (this.intervalId) {\n clearInterval(this.intervalId);\n this.intervalId = null;\n }\n if (this.store) this.store.removeItem(this.name);\n }\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// SPDX-FileCopyrightText: 2023-Present The Pepr Authors\n\nimport { K8s, KubernetesObject, RegisterKind } from \"kubernetes-fluent-client\";\nimport Log from \"./telemetry/logger\";\nimport { Binding } from \"./types\";\nimport { Operation } from \"./enums\";\nimport { PeprMutateRequest } from \"./mutate-request\";\nimport { DeepPartial } from \"./common-types\";\n\nexport function addFinalizer<K extends KubernetesObject>(request: PeprMutateRequest<K>): void {\n // if a DELETE is being processed, don't add a finalizer\n if (request.Request.operation === Operation.DELETE) {\n return;\n }\n\n // if an UPDATE is being processed and it HAS a deletionTimestamp, the\n // resource is going through a pre-delete flow so don't (re-)add a finalizer\n if (request.Request.operation === Operation.UPDATE && request.Raw.metadata?.deletionTimestamp) {\n return;\n }\n\n const peprFinal = \"pepr.dev/finalizer\";\n const finalizers = request.Raw.metadata?.finalizers || [];\n if (!finalizers.includes(peprFinal)) {\n finalizers.push(peprFinal);\n }\n\n request.Merge({ metadata: { finalizers } } as DeepPartial<K>);\n}\n\nexport async function removeFinalizer(binding: Binding, obj: KubernetesObject): Promise<void> {\n const peprFinal = \"pepr.dev/finalizer\";\n const meta = obj.metadata!;\n const resource = `${meta.namespace || \"ClusterScoped\"}/${meta.name}`;\n\n Log.debug({ obj }, `Removing finalizer '${peprFinal}' from '${resource}'`);\n\n // ensure request model is registerd with KFC (for non-built in CRD's, etc.)\n const { model, kind } = binding;\n try {\n RegisterKind(model, kind);\n } catch (e) {\n const expected = e.message === `GVK ${model.name} already registered`;\n if (!expected) {\n Log.error({ model, kind, error: e }, `Error registering \"${kind}\" during finalization.`);\n return;\n }\n }\n\n // remove pepr finalizers\n const finalizers = meta.finalizers?.filter(f => f !== peprFinal) || [];\n\n // JSON Patch - replace a key\n // https://datatracker.ietf.org/doc/html/rfc6902/#section-4.3\n obj = await K8s(model, meta).Patch([\n {\n op: \"replace\",\n path: `/metadata/finalizers`,\n value: finalizers,\n },\n ]);\n Log.debug({ obj }, `Removed finalizer '${peprFinal}' from '${resource}'`);\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// SPDX-FileCopyrightText: 2023-Present The Pepr Authors\nimport { clone } from \"ramda\";\nimport { Capability } from \"./capability\";\nimport { Controller } from \"../controller\";\nimport { ValidateError } from \"../errors\";\nimport { CapabilityExport } from \"../types\";\nimport { isBuildMode } from \"./envChecks\";\nimport { PackageJSON, PeprModuleOptions, ModuleConfig } from \"../types\";\nimport { createControllerHooks } from \"../controller/createHooks\";\n\nexport class PeprModule {\n #controller!: Controller;\n\n /**\n * Create a new Pepr runtime\n *\n * @param config The configuration for the Pepr runtime\n * @param capabilities The capabilities to be loaded into the Pepr runtime\n * @param opts Options for the Pepr runtime\n */\n constructor(\n { description, pepr }: PackageJSON,\n capabilities: Capability[] = [],\n opts: PeprModuleOptions = {},\n ) {\n const config: ModuleConfig = clone(pepr);\n config.description = description;\n\n // Need to validate at runtime since TS gets sad about parsing the package.json\n ValidateError(config.onError);\n\n // Handle build mode\n if (isBuildMode()) {\n // Fail if process.send is not defined\n if (!process.send) {\n throw new Error(\"process.send is not defined\");\n }\n\n const exportedCapabilities: CapabilityExport[] = [];\n\n // Send capability map to parent process\n for (const capability of capabilities) {\n // Convert the capability to a capability config\n exportedCapabilities.push({\n name: capability.name,\n description: capability.description,\n namespaces: capability.namespaces,\n bindings: capability.bindings,\n hasSchedule: capability.hasSchedule,\n });\n }\n\n // Send the capabilities back to the parent process\n process.send(exportedCapabilities);\n\n return;\n }\n\n const controllerHooks = createControllerHooks(\n opts,\n capabilities,\n pepr?.alwaysIgnore?.namespaces?.length\n ? pepr.alwaysIgnore.namespaces\n : config?.watch?.alwaysIgnore?.namespaces,\n );\n\n this.#controller = new Controller(config, capabilities, controllerHooks);\n\n // Stop processing if deferStart is set to true\n if (opts.deferStart) {\n return;\n }\n\n this.start();\n }\n\n /**\n * Start the Pepr runtime manually.\n * Normally this is called automatically when the Pepr module is instantiated, but can be called manually if `deferStart` is set to `true` in the constructor.\n *\n * @param port\n */\n start = (port = 3000): void => {\n this.#controller.startServer(port);\n };\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// SPDX-FileCopyrightText: 2023-Present The Pepr Authors\n\nimport express, { NextFunction } from \"express\";\nimport fs from \"fs\";\nimport https from \"https\";\n\nimport { Capability } from \"../core/capability\";\nimport { MutateResponse, ValidateResponse } from \"../k8s\";\nimport Log from \"../telemetry/logger\";\nimport { metricsCollector, MetricsCollector } from \"../telemetry/metrics\";\nimport { isWatchMode } from \"../core/envChecks\";\nimport { ModuleConfig } from \"../types\";\nimport { mutateProcessor } from \"../processors/mutate-processor\";\nimport { validateProcessor } from \"../processors/validate-processor\";\nimport { StoreController } from \"./store\";\nimport { karForMutate, karForValidate, KubeAdmissionReview } from \"./index.util\";\nimport { AdmissionRequest } from \"../common-types\";\nimport { featureFlagStore } from \"../features/store\";\n\nexport interface ControllerHooks {\n beforeHook?: (req: AdmissionRequest) => void;\n afterHook?: (res: MutateResponse | ValidateResponse) => void;\n onReady?: () => void;\n}\n\nif (!process.env.PEPR_NODE_WARNINGS) {\n process.removeAllListeners(\"warning\");\n}\n\nexport class Controller {\n // Track whether the server is running\n #running = false;\n\n // Metrics collector\n #metricsCollector = metricsCollector;\n\n // The path used to authenticate requests\n #path = \"\";\n\n // The express app instance\n readonly #app = express();\n\n // Initialized with the constructor\n readonly #config: ModuleConfig;\n readonly #capabilities: Capability[];\n readonly #beforeHook?: (req: AdmissionRequest) => void;\n readonly #afterHook?: (res: MutateResponse | ValidateResponse) => void;\n\n constructor(config: ModuleConfig, capabilities: Capability[], hooks: ControllerHooks = {}) {\n const { beforeHook, afterHook, onReady } = hooks;\n this.#config = config;\n this.#capabilities = capabilities;\n Log.info({ config }, \"Controller configuration\");\n\n // Initialize the Pepr store for each capability\n new StoreController(capabilities, `pepr-${config.uuid}-store`, () => {\n this.#bindEndpoints();\n if (typeof onReady === \"function\") {\n onReady();\n }\n Log.debug(\"Controller startup complete\");\n // Initialize the schedule store for each capability\n new StoreController(capabilities, `pepr-${config.uuid}-schedule`, () => {\n Log.debug(\"Scheduling processed\");\n });\n });\n\n // Middleware for logging requests\n this.#app.use(Controller.#logger);\n\n // Middleware for parsing JSON, limit to 2mb vs 100K for K8s compatibility\n this.#app.use(express.json({ limit: \"2mb\" }));\n\n if (beforeHook) {\n Log.info(`Using beforeHook: ${beforeHook}`);\n this.#beforeHook = beforeHook;\n }\n\n if (afterHook) {\n Log.info(`Using afterHook: ${afterHook}`);\n this.#afterHook = afterHook;\n }\n }\n\n /** Start the webhook server */\n startServer = (port: number): void => {\n if (this.#running) {\n throw new Error(\n \"Cannot start Pepr module: Pepr module was not instantiated with deferStart=true\",\n );\n }\n\n // Initialize feature store\n try {\n featureFlagStore.initialize();\n Log.info(`Feature flag store initialized: ${JSON.stringify(featureFlagStore.getAll())}`);\n } catch (error) {\n Log.warn(error, \"Could not initialize feature flags\");\n }\n // Load SSL certificate and key\n const options = {\n key: fs.readFileSync(process.env.SSL_KEY_PATH || \"/etc/certs/tls.key\"),\n cert: fs.readFileSync(process.env.SSL_CERT_PATH || \"/etc/certs/tls.crt\"),\n };\n\n // Get the API path if not in watch mode\n if (!isWatchMode()) {\n // Get the API path from the environment variable or the mounted secret\n this.#path =\n process.env.PEPR_API_PATH || fs.readFileSync(\"/app/api-path/value\").toString().trim();\n Log.info(`Using API path: ${this.#path}`);\n\n if (!this.#path) {\n throw new Error(\"API path not found\");\n }\n }\n\n // Create HTTPS server\n const server = https.createServer(options, this.#app).listen(port);\n\n // Handle server listening event\n server.on(\"listening\", () => {\n Log.debug(`Server listening on port ${port}`);\n // Track that the server is running\n this.#running = true;\n });\n\n // Handle EADDRINUSE errors\n server.on(\"error\", (e: { code: string }) => {\n if (e.code === \"EADDRINUSE\") {\n Log.info(\n `Address in use, retrying in 2 seconds. If this persists, ensure ${port} is not in use, e.g. \"lsof -i :${port}\"`,\n );\n setTimeout(() => {\n server.close();\n server.listen(port);\n }, 2000);\n }\n });\n\n // Listen for the SIGTERM signal and gracefully close the server\n process.on(\"SIGTERM\", () => {\n Log.info(\"Received SIGTERM, closing server.\");\n server.close(() => {\n Log.info(\"Server closed.\");\n process.exit(143);\n });\n });\n };\n\n #bindEndpoints = (): void => {\n // Health check endpoint\n this.#app.get(\"/healthz\", Controller.#healthz);\n\n // Metrics endpoint\n this.#app.get(\"/metrics\", this.#metrics);\n\n if (isWatchMode()) {\n return;\n }\n\n // Require auth for webhook endpoints\n this.#app.use([\"/mutate/:path\", \"/validate/:path\"], this.#validatepath);\n\n // Mutate endpoint\n this.#app.post(\"/mutate/:path\", this.#admissionReq(\"Mutate\"));\n\n // Validate endpoint\n this.#app.post(\"/validate/:path\", this.#admissionReq(\"Validate\"));\n };\n\n /**\n * Validate the path in the request path\n *\n * @param req The incoming request\n * @param res The outgoing response\n * @param next The next middleware function\n * @returns\n */\n #validatepath = (req: express.Request, res: express.Response, next: NextFunction): void => {\n // Validate the path\n const { path } = req.params;\n if (path !== this.#path) {\n const err = `Unauthorized: invalid path '${path.replace(/[^\\w]/g, \"_\")}'`;\n Log.info(err);\n res.status(401).send(err);\n this.#metricsCollector.alert();\n return;\n }\n\n // path is valid, continue\n next();\n };\n\n /**\n * Metrics endpoint handler\n *\n * @param req the incoming request\n * @param res the outgoing response\n */\n #metrics = async (req: express.Request, res: express.Response): Promise<void> => {\n try {\n // https://github.com/prometheus/docs/blob/main/content/docs/instrumenting/exposition_formats.md#basic-info\n res.set(\"Content-Type\", \"text/plain; version=0.0.4\");\n res.send(await this.#metricsCollector.getMetrics());\n } catch (err) {\n Log.error(err, `Error getting metrics`);\n res.status(500).send(\"Internal Server Error\");\n }\n };\n\n /**\n * Admission request handler for both mutate and validate requests\n *\n * @param admissionKind the type of admission request\n * @returns the request handler\n */\n #admissionReq = (\n admissionKind: \"Mutate\" | \"Validate\",\n ): ((req: express.Request, res: express.Response) => Promise<void>) => {\n // Create the admission request handler\n return async (req: express.Request, res: express.Response) => {\n // Start the metrics timer\n const startTime = MetricsCollector.observeStart();\n\n try {\n // Get the request from the body or create an empty request\n const request: AdmissionRequest = req.body?.request || ({} as AdmissionRequest);\n\n const { name, namespace, gvk } = {\n name: request?.name ? `/${request.name}` : \"\",\n namespace: request?.namespace || \"\",\n gvk: request?.kind || { group: \"\", version: \"\", kind: \"\" },\n };\n\n const reqMetadata = { uid: request.uid, namespace, name };\n Log.info(\n { ...reqMetadata, gvk, operation: request.operation, admissionKind },\n \"Incoming request\",\n );\n Log.debug({ ...reqMetadata, request }, \"Incoming request body\");\n\n // Run the before hook if it exists\n if (typeof this.#beforeHook === \"function\") {\n this.#beforeHook(request || {});\n }\n\n // Process the request\n const response: MutateResponse | ValidateResponse[] =\n admissionKind === \"Mutate\"\n ? await mutateProcessor(this.#config, this.#capabilities, request, reqMetadata)\n : await validateProcessor(this.#config, this.#capabilities, request, reqMetadata);\n\n // Run the after hook if it exists\n [response].flat().map(res => {\n if (typeof this.#afterHook === \"function\") {\n this.#afterHook(res);\n }\n Log.info({ ...reqMetadata, res }, \"Check response\");\n });\n\n const kar: KubeAdmissionReview =\n admissionKind === \"Mutate\"\n ? karForMutate(response as MutateResponse)\n : karForValidate(request, response as ValidateResponse[]);\n\n Log.debug({ ...reqMetadata, kubeAdmissionResponse: kar.response }, \"Outgoing response\");\n res.send(kar);\n\n this.#metricsCollector.observeEnd(startTime, admissionKind);\n } catch (err) {\n Log.error(err, `Error processing ${admissionKind} request`);\n res.status(500).send(\"Internal Server Error\");\n this.#metricsCollector.error();\n }\n };\n };\n\n /**\n * Middleware for logging requests\n *\n * @param req the incoming request\n * @param res the outgoing response\n * @param next the next middleware function\n */\n static #logger(req: express.Request, res: express.Response, next: express.NextFunction): void {\n const startTime = Date.now();\n\n res.on(\"finish\", () => {\n const excludedRoutes = [\"/healthz\", \"/metrics\"];\n if (excludedRoutes.includes(req.originalUrl)) {\n return;\n }\n\n const elapsedTime = Date.now() - startTime;\n const message = {\n uid: req.body?.request?.uid,\n method: req.method,\n url: req.originalUrl,\n status: res.statusCode,\n duration: `${elapsedTime} ms`,\n };\n\n Log.info(message);\n });\n\n next();\n }\n /**\n * Health check endpoint handler\n *\n * @param req the incoming request\n * @param res the outgoing response\n */\n static #healthz(req: express.Request, res: express.Response): void {\n try {\n res.send(\"OK\");\n } catch (err) {\n Log.error(err, `Error processing health check`);\n res.status(500).send(\"Internal Server Error\");\n }\n }\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// SPDX-FileCopyrightText: 2023-Present The Pepr Authors\n\nimport { performance } from \"perf_hooks\";\nimport promClient, { Counter, Registry, Gauge, Summary } from \"prom-client\";\nimport Log from \"./logger\";\n\nconst loggingPrefix = \"MetricsCollector\";\n\nexport type MetricsCollectorInstance = InstanceType<typeof MetricsCollector>;\ninterface MetricNames {\n errors: string;\n alerts: string;\n mutate: string;\n validate: string;\n cacheMiss: string;\n resyncFailureCount: string;\n}\n\ninterface MetricArgs {\n name: string;\n help: string;\n registers: Registry[];\n labelNames?: string[];\n}\n\n/**\n * MetricsCollector class handles metrics collection using prom-client and performance hooks.\n */\nexport class MetricsCollector {\n #registry: Registry;\n #counters: Map<string, Counter<string>> = new Map();\n #gauges: Map<string, Gauge<string>> = new Map();\n #summaries: Map<string, Summary<string>> = new Map();\n #prefix: string;\n #cacheMissWindows: Map<string, number> = new Map();\n\n #metricNames: MetricNames = {\n errors: \"errors\",\n alerts: \"alerts\",\n mutate: \"mutate\",\n validate: \"validate\",\n cacheMiss: \"cache_miss\",\n resyncFailureCount: \"resync_failure_count\",\n };\n\n /**\n * Creates a MetricsCollector instance with prefixed metrics.\n * @param [prefix='pepr'] - The prefix for the metric names.\n */\n constructor(prefix = \"pepr\") {\n this.#registry = new Registry();\n this.#prefix = prefix;\n this.addCounter(this.#metricNames.errors, \"Mutation/Validate errors encountered\");\n this.addCounter(this.#metricNames.alerts, \"Mutation/Validate bad api path received\");\n this.addSummary(this.#metricNames.mutate, \"Mutation operation summary\");\n this.addSummary(this.#metricNames.validate, \"Validation operation summary\");\n this.addGauge(this.#metricNames.cacheMiss, \"Number of cache misses per window\", [\"window\"]);\n this.addGauge(this.#metricNames.resyncFailureCount, \"Number of failures per resync operation\", [\n \"count\",\n ]);\n }\n\n #getMetricName = (name: string): string => `${this.#prefix}_${name}`;\n\n #addMetric = <T extends Counter<string> | Gauge<string> | Summary<string>>(\n collection: Map<string, T>,\n MetricType: new (args: MetricArgs) => T,\n { name, help, labelNames }: Omit<MetricArgs, \"registers\">,\n ): void => {\n if (collection.has(this.#getMetricName(name))) {\n Log.debug({ loggingPrefix }, `Metric for ${name} already exists`);\n return;\n }\n\n const metric = new MetricType({\n name: this.#getMetricName(name),\n help,\n registers: [this.#registry],\n labelNames,\n });\n\n collection.set(this.#getMetricName(name), metric);\n };\n\n addCounter = (name: string, help: string): void => {\n this.#addMetric(this.#counters, promClient.Counter, { name, help, labelNames: [] });\n };\n\n addSummary = (name: string, help: string): void => {\n this.#addMetric(this.#summaries, promClient.Summary, { name, help, labelNames: [] });\n };\n\n addGauge = (name: string, help: string, labelNames?: string[]): void => {\n this.#addMetric(this.#gauges, promClient.Gauge, { name, help, labelNames });\n };\n\n incCounter = (name: string): void => {\n this.#counters.get(this.#getMetricName(name))?.inc();\n };\n\n incGauge = (name: string, labels?: Record<string, string>, value: number = 1): void => {\n this.#gauges.get(this.#getMetricName(name))?.inc(labels || {}, value);\n };\n\n /**\n * Increments the error counter.\n */\n error = (): void => this.incCounter(this.#metricNames.errors);\n\n /**\n * Increments the alerts counter.\n */\n alert = (): void => this.incCounter(this.#metricNames.alerts);\n\n /**\n * Observes the duration since the provided start time and updates the summary.\n * @param startTime - The start time.\n * @param name - The metrics summary to increment.\n */\n observeEnd = (startTime: number, name: string = this.#metricNames.mutate): void => {\n this.#summaries.get(this.#getMetricName(name))?.observe(performance.now() - startTime);\n };\n\n /**\n * Fetches the current metrics from the registry.\n * @returns The metrics.\n */\n getMetrics = (): Promise<string> => this.#registry.metrics();\n\n /**\n * Returns the current timestamp from performance.now() method. Useful for start timing an operation.\n * @returns The timestamp.\n */\n static observeStart(): number {\n return performance.now();\n }\n\n /**\n * Increments the cache miss gauge for a given label.\n * @param label - The label for the cache miss.\n */\n incCacheMiss = (window: string): void => {\n this.incGauge(this.#metricNames.cacheMiss, { window });\n };\n\n /**\n * Increments the retry count gauge.\n * @param count - The count to increment by.\n */\n incRetryCount = (count: number): void => {\n this.incGauge(this.#metricNames.resyncFailureCount, { count: count.toString() });\n };\n\n /**\n * Initializes the cache miss gauge for a given label.\n * @param label - The label for the cache miss.\n */\n initCacheMissWindow = (window: string): void => {\n this.#rollCacheMissWindows();\n this.#gauges.get(this.#getMetricName(this.#metricNames.cacheMiss))?.set({ window }, 0);\n this.#cacheMissWindows.set(window, 0);\n };\n\n /**\n * Manages the size of the cache miss gauge map.\n */\n #rollCacheMissWindows = (): void => {\n const maxCacheMissWindows = process.env.PEPR_MAX_CACHE_MISS_WINDOWS\n ? parseInt(process.env.PEPR_MAX_CACHE_MISS_WINDOWS, 10)\n : undefined;\n\n if (maxCacheMissWindows !== undefined && this.#cacheMissWindows.size >= maxCacheMissWindows) {\n const firstKey = this.#cacheMissWindows.keys().next().value;\n if (firstKey !== undefined) {\n this.#cacheMissWindows.delete(firstKey);\n }\n this.#gauges\n .get(this.#getMetricName(this.#metricNames.cacheMiss))\n ?.remove({ window: firstKey });\n }\n };\n}\n\nexport const metricsCollector: MetricsCollectorInstance = new MetricsCollector(\"pepr\");\n", "// SPDX-License-Identifier: Apache-2.0\n// SPDX-FileCopyrightText: 2023-Present The Pepr Authors\n\nimport jsonPatch from \"fast-json-patch\";\nimport { KubernetesObject } from \"kubernetes-fluent-client\";\nimport { MeasureWebhookTimeout } from \"../telemetry/webhookTimeouts\";\nimport { Capability } from \"../core/capability\";\nimport { shouldSkipRequest } from \"../filter/filter\";\nimport { MutateResponse } from \"../k8s\";\nimport { Binding } from \"../types\";\nimport Log from \"../telemetry/logger\";\nimport { ModuleConfig } from \"../types\";\nimport { PeprMutateRequest } from \"../mutate-request\";\nimport { base64Encode } from \"../utils\";\nimport { OnError } from \"../../cli/init/enums\";\nimport { resolveIgnoreNamespaces } from \"../assets/ignoredNamespaces\";\nimport { Operation } from \"fast-json-patch\";\nimport { WebhookType } from \"../enums\";\n\nimport { AdmissionRequest } from \"../common-types\";\n\nimport { decodeData, reencodeData } from \"./decode-utils\";\n\nexport interface Bindable {\n req: AdmissionRequest;\n config: ModuleConfig;\n name: string;\n namespaces: string[];\n binding: Binding;\n actMeta: Record<string, string>;\n}\n\ninterface Result {\n wrapped: PeprMutateRequest<KubernetesObject>;\n response: MutateResponse;\n}\n\n// Add annotations to the request to indicate that the capability started processing\n// this will allow tracking of failed mutations that were permitted to continue\nexport function updateStatus(\n config: ModuleConfig,\n name: string,\n wrapped: PeprMutateRequest<KubernetesObject>,\n status: string,\n): PeprMutateRequest<KubernetesObject> {\n // Only update the status if the request is a CREATE or UPDATE (we don't use CONNECT)\n if (wrapped.Request.operation === \"DELETE\") {\n return wrapped;\n }\n wrapped.SetAnnotation(`${config.uuid}.pepr.dev/${name}`, status);\n\n return wrapped;\n}\n\nexport function logMutateErrorMessage(e: Error): string {\n try {\n if (e.message && e.message !== \"[object Object]\") {\n return e.message;\n } else {\n throw new Error(\"An error occurred in the mutate action.\");\n }\n } catch {\n return \"An error occurred with the mutate action.\";\n }\n}\n\nexport async function processRequest(\n bindable: Bindable,\n wrapped: PeprMutateRequest<KubernetesObject>,\n response: MutateResponse,\n): Promise<Result> {\n const { binding, actMeta, name, config } = bindable;\n\n const label = binding.mutateCallback!.name;\n Log.info(actMeta, `Processing mutation action (${label})`);\n\n wrapped = updateStatus(config, name, wrapped, \"started\");\n\n try {\n // Run the action\n await binding.mutateCallback!(wrapped);\n\n // Log on success\n Log.info(actMeta, `Mutation action succeeded (${label})`);\n\n // Add annotations to the request to indicate that the capability succeeded\n wrapped = updateStatus(config, name, wrapped, \"succeeded\");\n } catch (e) {\n wrapped = updateStatus(config, name, wrapped, \"warning\");\n response.warnings = response.warnings || [];\n\n const errorMessage = logMutateErrorMessage(e);\n\n // Log on failure\n Log.error(actMeta, `Action failed: ${errorMessage}`);\n response.warnings.push(`Action failed: ${errorMessage}`);\n\n switch (config.onError) {\n case OnError.REJECT:\n response.result = \"Pepr module configured to reject on error\";\n break;\n\n case OnError.AUDIT:\n response.auditAnnotations = response.auditAnnotations || {};\n response.auditAnnotations[Date.now()] = `Action failed: ${errorMessage}`;\n break;\n }\n }\n\n return { wrapped, response };\n}\n\n/* eslint max-statements: [\"warn\", 25] */\nexport async function mutateProcessor(\n config: ModuleConfig,\n capabilities: Capability[],\n req: AdmissionRequest,\n reqMetadata: Record<string, string>,\n): Promise<MutateResponse> {\n const webhookTimer = new MeasureWebhookTimeout(WebhookType.MUTATE);\n webhookTimer.start(config.webhookTimeout);\n let response: MutateResponse = {\n uid: req.uid,\n warnings: [],\n allowed: false,\n };\n\n const decoded = decodeData(new PeprMutateRequest(req));\n let wrapped = decoded.wrapped;\n\n Log.info(reqMetadata, `Processing request`);\n const bindables: Bindable[] = capabilities\n .flatMap(capa =>\n capa.bindings.map(bind => ({\n req,\n config,\n name: capa.name,\n namespaces: capa.namespaces,\n binding: bind,\n actMeta: { ...reqMetadata, name: capa.name },\n })),\n )\n .filter(bind => {\n if (!bind.binding.mutateCallback) {\n return false;\n }\n\n const shouldSkip = shouldSkipRequest(\n bind.binding,\n bind.req,\n bind.namespaces,\n resolveIgnoreNamespaces(\n bind?.config?.alwaysIgnore?.namespaces?.length\n ? bind.config?.alwaysIgnore?.namespaces\n : bind.config?.admission?.alwaysIgnore?.namespaces,\n ),\n );\n if (shouldSkip !== \"\") {\n Log.debug(shouldSkip);\n return false;\n }\n\n return true;\n });\n\n for (const bindable of bindables) {\n ({ wrapped, response } = await processRequest(bindable, wrapped, response));\n if (config.onError === OnError.REJECT && response?.warnings!.length > 0) {\n webhookTimer.stop();\n return response;\n }\n }\n\n // The request is allowed\n\n // If no capability matched the request, exit early\n if (bindables.length === 0) {\n Log.info(reqMetadata, `No matching actions found`);\n webhookTimer.stop();\n return { ...response, allowed: true };\n }\n\n // delete operations can't be mutate, just return before the transformation\n if (req.operation === \"DELETE\") {\n webhookTimer.stop();\n return { ...response, allowed: true };\n }\n\n // unskip base64-encoded data fields that were skipDecode'd\n const transformed = reencodeData(wrapped, decoded.skipped);\n\n // Compare the original request to the modified request to get the patches\n const patches = jsonPatch.compare(req.object, transformed);\n\n updateResponsePatchAndWarnings(patches, response);\n\n Log.debug({ ...reqMetadata, patches }, `Patches generated`);\n webhookTimer.stop();\n return { ...response, allowed: true };\n}\n\nexport function updateResponsePatchAndWarnings(\n patches: Operation[],\n response: MutateResponse,\n): void {\n // Only add the patch if there are patches to apply\n if (patches.length > 0) {\n response.patchType = \"JSONPatch\";\n // Webhook must be base64-encoded\n // https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#response\n response.patch = base64Encode(JSON.stringify(patches));\n }\n\n // Remove the warnings array if it's empty\n if (response.warnings && response.warnings.length < 1) {\n delete response.warnings;\n }\n}\n", "export const getNow = (): number => performance.now();\n", "import { metricsCollector } from \"./metrics\";\nimport { getNow } from \"./timeUtils\";\nimport Log from \"./logger\";\nimport { WebhookType } from \"../enums\";\nexport class MeasureWebhookTimeout {\n #startTime: number | null = null;\n #webhookType: string;\n timeout: number = 0;\n\n constructor(webhookType: WebhookType) {\n this.#webhookType = webhookType;\n metricsCollector.addCounter(\n `${webhookType}_timeouts`,\n `Number of ${webhookType} webhook timeouts`,\n );\n }\n\n start(timeout: number = 10): void {\n this.#startTime = getNow();\n this.timeout = timeout;\n Log.debug(`Starting timer at ${this.#startTime}`);\n }\n\n stop(): void {\n if (this.#startTime === null) {\n throw new Error(\"Timer was not started before calling stop.\");\n }\n\n const elapsedTime = getNow() - this.#startTime;\n Log.debug(`Webhook ${this.#startTime} took ${elapsedTime}ms`);\n this.#startTime = null;\n\n if (elapsedTime > this.timeout) {\n metricsCollector.incCounter(`${this.#webhookType}_timeouts`);\n }\n }\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// SPDX-FileCopyrightText: 2023-Present The Pepr Authors\n\nimport { Operation } from \"../../enums\";\nimport { defaultTo, pipe } from \"ramda\";\nimport { KubernetesObject } from \"kubernetes-fluent-client\";\nimport { AdmissionRequest } from \"../../common-types\";\n\nexport const declaredOperation = pipe(\n (request: AdmissionRequest<KubernetesObject>): Operation => request?.operation,\n defaultTo(\"\"),\n);\nexport const declaredGroup = pipe(\n (request: AdmissionRequest<KubernetesObject>): string => request?.kind?.group,\n defaultTo(\"\"),\n);\nexport const declaredVersion = pipe(\n (request: AdmissionRequest<KubernetesObject>): string | undefined => request?.kind?.version,\n defaultTo(\"\"),\n);\nexport const declaredKind = pipe(\n (request: AdmissionRequest<KubernetesObject>): string => request?.kind?.kind,\n defaultTo(\"\"),\n);\nexport const declaredUid = pipe(\n (request: AdmissionRequest<KubernetesObject>): string => request?.uid,\n defaultTo(\"\"),\n);\n", "// SPDX-License-Identifier: Apache-2.0\n// SPDX-FileCopyrightText: 2023-Present The Pepr Authors\n\nimport { Event } from \"../../enums\";\nimport { Binding, FinalizeAction, WatchLogAction, MutateAction, ValidateAction } from \"../../types\";\nimport { complement, defaultTo, equals, not, pipe } from \"ramda\";\nimport { GenericClass } from \"kubernetes-fluent-client\";\n\nexport const definesDeletionTimestamp = pipe(\n (binding: Binding): boolean => binding?.filters?.deletionTimestamp ?? false,\n defaultTo(false),\n);\nexport const ignoresDeletionTimestamp = complement(definesDeletionTimestamp);\n\nexport const definedName = pipe((binding: Binding): string => {\n return binding.filters.name;\n}, defaultTo(\"\"));\nexport const definesName = pipe(definedName, equals(\"\"), not);\nexport const ignoresName = complement(definesName);\n\nexport const definedNameRegex = pipe(\n (binding: Partial<Binding>): string | undefined => binding.filters?.regexName,\n defaultTo(\"\"),\n);\nexport const definesNameRegex = pipe(definedNameRegex, equals(\"\"), not);\n\nexport const definedNamespaces = pipe(binding => binding?.filters?.namespaces, defaultTo([]));\nexport const definesNamespaces = pipe(definedNamespaces, equals([]), not);\n\nexport const definedNamespaceRegexes = pipe(\n binding => binding?.filters?.regexNamespaces,\n defaultTo([]),\n);\nexport const definesNamespaceRegexes = pipe(definedNamespaceRegexes, equals([]), not);\n\nexport const definedAnnotations = pipe(\n (binding: Partial<Binding>) => binding?.filters?.annotations,\n defaultTo({}),\n);\nexport const definesAnnotations = pipe(definedAnnotations, equals({}), not);\n\nexport const definedLabels = pipe(\n (binding: Partial<Binding>) => binding?.filters?.labels,\n defaultTo({}),\n);\nexport const definesLabels = pipe(definedLabels, equals({}), not);\n\nexport const definedEvent = (binding: Binding): Event => {\n return binding.event;\n};\n\nexport const definesDelete = (binding: Binding): boolean => definedEvent(binding) === Event.DELETE;\n\nexport const definedGroup = pipe((binding): string => binding?.kind?.group, defaultTo(\"\"));\nexport const definesGroup = pipe(definedGroup, equals(\"\"), not);\n\nexport const definedVersion = pipe(\n (binding: Partial<Binding>): string | undefined => binding?.kind?.version,\n defaultTo(\"\"),\n);\nexport const definesVersion = pipe(definedVersion, equals(\"\"), not);\n\nexport const definedKind = pipe((binding): string => binding?.kind?.kind, defaultTo(\"\"));\nexport const definesKind = pipe(definedKind, equals(\"\"), not);\n\nexport const definedCategory = (binding: Partial<Binding>): string => {\n // Ordering matters, finalize is a \"watch\"\n const categories: { [key: string]: boolean | undefined } = {\n Finalize: binding.isFinalize,\n Watch: binding.isWatch,\n Mutate: binding.isMutate,\n Validate: binding.isValidate,\n };\n\n return Object.keys(categories).find(key => categories[key]) || \"\";\n};\n\ntype DefinedCallbackReturnType =\n | FinalizeAction<GenericClass, InstanceType<GenericClass>>\n | WatchLogAction<GenericClass, InstanceType<GenericClass>>\n | MutateAction<GenericClass, InstanceType<GenericClass>>\n | ValidateAction<GenericClass, InstanceType<GenericClass>>\n | null\n | undefined;\n\nexport const definedCallback = (binding: Partial<Binding>): DefinedCallbackReturnType => {\n // Ordering matters, finalize is a \"watch\"\n // prettier-ignore\n return binding.isFinalize ? binding.finalizeCallback :\n binding.isWatch ? binding.watchCallback :\n binding.isMutate ? binding.mutateCallback :\n binding.isValidate ? binding.validateCallback :\n null;\n};\nexport const definedCallbackName = pipe(\n definedCallback,\n defaultTo({ name: \"\" }),\n callback => callback.name,\n);\n", "// SPDX-License-Identifier: Apache-2.0\n// SPDX-FileCopyrightText: 2023-Present The Pepr Authors\n\nimport { __, allPass, complement, defaultTo, equals, length, gt, not, nthArg, pipe } from \"ramda\";\nimport { KubernetesObject } from \"kubernetes-fluent-client\";\n\nconst carriesDeletionTimestamp = pipe(\n kubernetesObject => !!kubernetesObject.metadata?.deletionTimestamp,\n defaultTo(false),\n);\nexport const missingDeletionTimestamp = complement(carriesDeletionTimestamp);\n\nexport const carriedKind = pipe(\n (kubernetesObject: KubernetesObject): string | undefined => kubernetesObject?.kind,\n defaultTo(\"not set\"),\n);\nexport const carriedVersion = pipe(\n (kubernetesObject: KubernetesObject): string | undefined =>\n kubernetesObject?.metadata?.resourceVersion,\n defaultTo(\"not set\"),\n);\nexport const carriedName = pipe(\n (kubernetesObject: KubernetesObject): string | undefined => kubernetesObject?.metadata?.name,\n defaultTo(\"\"),\n);\nexport const carriesName = pipe(carriedName, equals(\"\"), not);\nexport const missingName = complement(carriesName);\n\nexport const carriedNamespace = pipe(\n (kubernetesObject: KubernetesObject): string | undefined => kubernetesObject?.metadata?.namespace,\n defaultTo(\"\"),\n);\n\nexport const carriesNamespace = pipe(carriedNamespace, equals(\"\"), not);\n\nexport const carriedAnnotations = pipe(\n (kubernetesObject: KubernetesObject): { [key: string]: string } | undefined =>\n kubernetesObject?.metadata?.annotations,\n defaultTo({}),\n);\nexport const carriesAnnotations = pipe(carriedAnnotations, equals({}), not);\n\nexport const carriedLabels = pipe(\n (kubernetesObject: KubernetesObject): { [key: string]: string } | undefined =>\n kubernetesObject?.metadata?.labels,\n defaultTo({}),\n);\nexport const carriesLabels = pipe(carriedLabels, equals({}), not);\n\n/*\n * If the object does not have a namespace, and it is not a namespace,\n * then we must return false because it cannot be uncarryable\n */\nexport const uncarryableNamespace = allPass([\n pipe(nthArg(0), length, gt(__, 0)),\n pipe((namespaceSelector, kubernetesObject) => {\n if (kubernetesObject?.kind === \"Namespace\") {\n return namespaceSelector.includes(kubernetesObject?.metadata?.name);\n }\n if (carriesNamespace(kubernetesObject)) {\n return namespaceSelector.includes(carriedNamespace(kubernetesObject));\n }\n return true;\n }, not),\n]);\n\n/*\n * Returns true if the object is missing a carriable namespace.\n * - If the object is a Namespace, it returns true if its name is not in the namespaceSelector.\n * - Otherwise, it returns true if the object does not carry a namespace.\n */\nexport const missingCarriableNamespace = allPass([\n pipe(nthArg(0), length, gt(__, 0)),\n pipe((namespaceSelector: string[], kubernetesObject: KubernetesObject): boolean =>\n kubernetesObject.kind === \"Namespace\"\n ? !namespaceSelector.includes(kubernetesObject.metadata!.name!)\n : !carriesNamespace(kubernetesObject),\n ),\n]);\n\n/*\n * If the object does not have a namespace, and it is not a namespace,\n * then we must return false because it cannot be ignored\n */\nexport const carriesIgnoredNamespace = allPass([\n pipe(nthArg(0), length, gt(__, 0)),\n pipe((namespaceSelector, kubernetesObject) => {\n if (kubernetesObject?.kind === \"Namespace\") {\n return namespaceSelector.includes(kubernetesObject?.metadata?.name);\n }\n if (carriesNamespace(kubernetesObject)) {\n return namespaceSelector.includes(carriedNamespace(kubernetesObject));\n }\n\n return false;\n }),\n]);\n", "// SPDX-License-Identifier: Apache-2.0\n// SPDX-FileCopyrightText: 2023-Present The Pepr Authors\n\nimport { Binding } from \"../../types\";\nimport { allPass, any, anyPass, equals, not, nthArg, pipe } from \"ramda\";\nimport {\n definedAnnotations,\n definedEvent,\n definedGroup,\n definedKind,\n definedLabels,\n definedName,\n definedNameRegex,\n definedNamespaceRegexes,\n definedNamespaces,\n definedVersion,\n definesAnnotations,\n definesDeletionTimestamp,\n definesGroup,\n definesKind,\n definesLabels,\n definesName,\n definesNameRegex,\n definesNamespaceRegexes,\n definesNamespaces,\n definesVersion,\n} from \"./binding\";\nimport {\n carriedAnnotations,\n carriedLabels,\n carriedName,\n carriedNamespace,\n missingDeletionTimestamp,\n} from \"./kubernetesObject\";\nimport {\n declaredOperation,\n declaredGroup,\n declaredVersion,\n declaredKind,\n} from \"./admissionRequest\";\nimport { Event, Operation } from \"../../enums\";\nimport { AdmissionRequest } from \"../../common-types\";\n\nexport const mismatchedDeletionTimestamp = allPass([\n pipe(nthArg(0), definesDeletionTimestamp),\n pipe(nthArg(1), missingDeletionTimestamp),\n]);\n\nexport const mismatchedName = allPass([\n pipe(nthArg(0), definesName),\n pipe((binding, kubernetesObject) => definedName(binding) !== carriedName(kubernetesObject)),\n]);\n\nexport const mismatchedNameRegex = allPass([\n pipe(nthArg(0), definesNameRegex),\n pipe(\n (binding, kubernetesObject) =>\n new RegExp(definedNameRegex(binding)).test(carriedName(kubernetesObject)),\n not,\n ),\n]);\n\nexport const mismatchedNamespace = allPass([\n pipe(nthArg(0), definesNamespaces),\n pipe(\n (binding, kubernetesObject) =>\n definedNamespaces(binding).includes(carriedNamespace(kubernetesObject)),\n not,\n ),\n]);\n\nexport const mismatchedNamespaceRegex = allPass([\n pipe(nthArg(0), definesNamespaceRegexes),\n pipe((binding, kubernetesObject) =>\n pipe(\n any((regEx: string) => new RegExp(regEx).test(carriedNamespace(kubernetesObject))),\n not,\n )(definedNamespaceRegexes(binding)),\n ),\n]);\n\nexport const metasMismatch = pipe(\n (defined, carried) => {\n const result = { defined, carried, unalike: {} };\n\n result.unalike = Object.entries(result.defined)\n .map(([key, value]) => {\n const keyMissing = !Object.hasOwn(result.carried, key);\n const noValue = !value;\n const valMissing = !result.carried[key];\n const valDiffers = result.carried[key] !== result.defined[key];\n\n // prettier-ignore\n return (\n keyMissing ? { [key]: value } :\n noValue ? {} :\n valMissing ? { [key]: value } :\n valDiffers ? { [key]: value } :\n {}\n )\n })\n .reduce((acc, cur) => ({ ...acc, ...cur }), {});\n\n return result.unalike;\n },\n unalike => Object.keys(unalike).length > 0,\n);\n\nexport const mismatchedAnnotations = allPass([\n pipe(nthArg(0), definesAnnotations),\n pipe((binding, kubernetesObject) =>\n metasMismatch(definedAnnotations(binding), carriedAnnotations(kubernetesObject)),\n ),\n]);\n\nexport const mismatchedLabels = allPass([\n pipe(nthArg(0), definesLabels),\n pipe((binding, kubernetesObject) =>\n metasMismatch(definedLabels(binding), carriedLabels(kubernetesObject)),\n ),\n]);\n\nexport const mismatchedEvent = pipe(\n (binding: Binding, request: AdmissionRequest): boolean =>\n operationMatchesEvent(declaredOperation(request), definedEvent(binding)),\n not,\n);\n\nexport const mismatchedGroup = allPass([\n pipe(nthArg(0), definesGroup),\n pipe((binding, request) => definedGroup(binding) !== declaredGroup(request)),\n]);\n\nexport const mismatchedVersion = allPass([\n pipe(nthArg(0), definesVersion),\n pipe((binding, request) => definedVersion(binding) !== declaredVersion(request)),\n]);\n\nexport const mismatchedKind = allPass([\n pipe(nthArg(0), definesKind),\n pipe((binding, request) => definedKind(binding) !== declaredKind(request)),\n]);\nexport const operationMatchesEvent = anyPass([\n pipe(nthArg(1), equals(Event.ANY)),\n pipe((operation: Operation, event: Event): boolean => operation.valueOf() === event.valueOf()),\n pipe((operation: Operation, event: Event): boolean =>\n operation ? event.includes(operation) : false,\n ),\n]);\n", "// SPDX-License-Identifier: Apache-2.0\n// SPDX-FileCopyrightText: 2023-Present The Pepr Authors\n\nimport { __, allPass, curry, difference, equals, gt, length, not, nthArg, pipe } from \"ramda\";\nimport { KubernetesObject } from \"kubernetes-fluent-client\";\nimport {\n definedKind,\n definedNamespaces,\n definesDelete,\n definesDeletionTimestamp,\n definesNamespaces,\n} from \"./binding\";\nimport { carriedNamespace, carriesNamespace } from \"./kubernetesObject\";\n\n/*\n Naming scheme:\n - AdmissionRequest - \"declares\" / \"neglects\"\n - KubernetesObject - \"carries\" / \"missing\"\n - Binding - \"defines\" / \"ignores\"\n*/\n\nexport const bindsToKind = curry(\n allPass([\n pipe(nthArg(0), definedKind, equals(\"\"), not),\n pipe((binding, kind) => definedKind(binding) === kind),\n ]),\n);\nexport const bindsToNamespace = curry(pipe(bindsToKind(__, \"Namespace\")));\nexport const misboundNamespace = allPass([bindsToNamespace, definesNamespaces]);\n\n/*\n * If the object does not have a namespace, and it is not a namespace,\n * then we must return false because it cannot be uncarryable\n */\nexport const uncarryableNamespace = allPass([\n pipe(nthArg(0), length, gt(__, 0)),\n pipe((namespaceSelector, kubernetesObject) => {\n if (kubernetesObject?.kind === \"Namespace\") {\n return namespaceSelector.includes(kubernetesObject?.metadata?.name);\n }\n if (carriesNamespace(kubernetesObject)) {\n return namespaceSelector.includes(carriedNamespace(kubernetesObject));\n }\n return true;\n }, not),\n]);\n\nexport const missingCarriableNamespace = allPass([\n pipe(nthArg(0), length, gt(__, 0)),\n pipe((namespaceSelector: string[], kubernetesObject: KubernetesObject): boolean =>\n kubernetesObject.kind === \"Namespace\"\n ? !namespaceSelector.includes(kubernetesObject.metadata!.name!)\n : !carriesNamespace(kubernetesObject),\n ),\n]);\n\n/*\n * If the object does not have a namespace, and it is not a namespace,\n * then we must return false because it cannot be ignored\n */\nexport const carriesIgnoredNamespace = allPass([\n pipe(nthArg(0), length, gt(__, 0)),\n pipe((namespaceSelector, kubernetesObject) => {\n if (kubernetesObject?.kind === \"Namespace\") {\n return namespaceSelector.includes(kubernetesObject?.metadata?.name);\n }\n if (carriesNamespace(kubernetesObject)) {\n return namespaceSelector.includes(carriedNamespace(kubernetesObject));\n }\n\n return false;\n }),\n]);\n\nexport const unbindableNamespaces = allPass([\n pipe(nthArg(0), length, gt(__, 0)),\n pipe(nthArg(1), definesNamespaces),\n pipe(\n (namespaceSelector, binding) => difference(definedNamespaces(binding), namespaceSelector),\n length,\n equals(0),\n not,\n ),\n]);\n\nexport const misboundDeleteWithDeletionTimestamp = allPass([\n definesDelete,\n definesDeletionTimestamp,\n]);\n", "import { KubernetesObject } from \"kubernetes-fluent-client\";\nimport { AdmissionRequest } from \"../common-types\";\nimport { Binding } from \"../types\";\nimport {\n declaredOperation,\n declaredGroup,\n declaredVersion,\n declaredKind,\n} from \"./adjudicators/admissionRequest\";\nimport {\n definedEvent,\n definedName,\n definedGroup,\n definedVersion,\n definedKind,\n definedNamespaces,\n definedLabels,\n definedAnnotations,\n definedNamespaceRegexes,\n definedNameRegex,\n} from \"./adjudicators/binding\";\nimport {\n carriedName,\n carriedNamespace,\n carriedLabels,\n carriedAnnotations,\n} from \"./adjudicators/kubernetesObject\";\nimport {\n mismatchedDeletionTimestamp,\n mismatchedEvent,\n mismatchedName,\n mismatchedGroup,\n mismatchedVersion,\n mismatchedKind,\n mismatchedNamespace,\n mismatchedLabels,\n mismatchedAnnotations,\n mismatchedNamespaceRegex,\n mismatchedNameRegex,\n} from \"./adjudicators/mismatch\";\nimport {\n misboundNamespace,\n misboundDeleteWithDeletionTimestamp,\n unbindableNamespaces,\n uncarryableNamespace,\n carriesIgnoredNamespace,\n missingCarriableNamespace,\n} from \"./adjudicators/postCollection\";\nimport { AdjudicationResult } from \"../types\";\n\nexport function adjudicateMisboundNamespace(binding: Binding): AdjudicationResult {\n return misboundNamespace(binding) ? \"Cannot use namespace filter on a namespace object.\" : null;\n}\n\nexport function adjudicateMisboundDeleteWithDeletionTimestamp(\n binding: Binding,\n): AdjudicationResult {\n return misboundDeleteWithDeletionTimestamp(binding)\n ? \"Cannot use deletionTimestamp filter on a DELETE operation.\"\n : null;\n}\n\nexport function adjudicateMismatchedDeletionTimestamp(\n binding: Binding,\n obj: KubernetesObject,\n): AdjudicationResult {\n return mismatchedDeletionTimestamp(binding, obj)\n ? \"Binding defines deletionTimestamp but Object does not carry it.\"\n : null;\n}\n\nexport function adjudicateMismatchedEvent(\n binding: Binding,\n req: AdmissionRequest,\n): AdjudicationResult {\n return mismatchedEvent(binding, req)\n ? `Binding defines event '${definedEvent(binding)}' but Request declares '${declaredOperation(req)}'.`\n : null;\n}\n\nexport function adjudicateMismatchedName(\n binding: Binding,\n obj: KubernetesObject,\n): AdjudicationResult {\n return mismatchedName(binding, obj)\n ? `Binding defines name '${definedName(binding)}' but Object carries '${carriedName(obj)}'.`\n : null;\n}\n\nexport function adjudicateMismatchedGroup(\n binding: Binding,\n req: AdmissionRequest,\n): AdjudicationResult {\n return mismatchedGroup(binding, req)\n ? `Binding defines group '${definedGroup(binding)}' but Request declares '${declaredGroup(req)}'.`\n : null;\n}\n\nexport function adjudicateMismatchedVersion(\n binding: Binding,\n req: AdmissionRequest,\n): AdjudicationResult {\n return mismatchedVersion(binding, req)\n ? `Binding defines version '${definedVersion(binding)}' but Request declares '${declaredVersion(req)}'.`\n : null;\n}\n\nexport function adjudicateMismatchedKind(\n binding: Binding,\n req: AdmissionRequest,\n): AdjudicationResult {\n return mismatchedKind(binding, req)\n ? `Binding defines kind '${definedKind(binding)}' but Request declares '${declaredKind(req)}'.`\n : null;\n}\n\nexport function adjudicateUnbindableNamespaces(\n capabilityNamespaces: string[],\n binding: Binding,\n): AdjudicationResult {\n return unbindableNamespaces(capabilityNamespaces, binding)\n ? `Binding defines namespaces ${JSON.stringify(definedNamespaces(binding))} but namespaces allowed by Capability are '${JSON.stringify(capabilityNamespaces)}'.`\n : null;\n}\n\nexport function adjudicateUncarryableNamespace(\n capabilityNamespaces: string[],\n obj: KubernetesObject,\n): AdjudicationResult {\n return uncarryableNamespace(capabilityNamespaces, obj)\n ? `Object carries namespace '${obj.kind && obj.kind === \"Namespace\" ? obj.metadata?.name : carriedNamespace(obj)}' but namespaces allowed by Capability are '${JSON.stringify(capabilityNamespaces)}'.`\n : null;\n}\n\nexport function adjudicateMismatchedNamespace(\n binding: Binding,\n obj: KubernetesObject,\n): AdjudicationResult {\n return mismatchedNamespace(binding, obj)\n ? `Binding defines namespaces '${JSON.stringify(definedNamespaces(binding))}' but Object carries '${carriedNamespace(obj)}'.`\n : null;\n}\n\nexport function adjudicateMismatchedLabels(\n binding: Binding,\n obj: KubernetesObject,\n): AdjudicationResult {\n return mismatchedLabels(binding, obj)\n ? `Binding defines labels '${JSON.stringify(definedLabels(binding))}' but Object carries '${JSON.stringify(carriedLabels(obj))}'.`\n : null;\n}\n\nexport function adjudicateMismatchedAnnotations(\n binding: Binding,\n obj: KubernetesObject,\n): AdjudicationResult {\n return mismatchedAnnotations(binding, obj)\n ? `Binding defines annotations '${JSON.stringify(definedAnnotations(binding))}' but Object carries '${JSON.stringify(carriedAnnotations(obj))}'.`\n : null;\n}\n\nexport function adjudicateMismatchedNamespaceRegex(\n binding: Binding,\n obj: KubernetesObject,\n): AdjudicationResult {\n return mismatchedNamespaceRegex(binding, obj)\n ? `Binding defines namespace regexes '${JSON.stringify(definedNamespaceRegexes(binding))}' but Object carries '${carriedNamespace(obj)}'.`\n : null;\n}\n\nexport function adjudicateMismatchedNameRegex(\n binding: Binding,\n obj: KubernetesObject,\n): AdjudicationResult {\n return mismatchedNameRegex(binding, obj)\n ? `Binding defines name regex '${definedNameRegex(binding)}' but Object carries '${carriedName(obj)}'.`\n : null;\n}\n\nexport function adjudicateCarriesIgnoredNamespace(\n ignoredNamespaces: string[] | undefined,\n obj: KubernetesObject,\n): AdjudicationResult {\n return carriesIgnoredNamespace(ignoredNamespaces, obj)\n ? `Object carries namespace '${obj.kind && obj.kind === \"Namespace\" ? obj.metadata?.name : carriedNamespace(obj)}' but ignored namespaces include '${JSON.stringify(ignoredNamespaces)}'.`\n : null;\n}\n\nexport function adjudicateMissingCarriableNamespace(\n capabilityNamespaces: string[],\n obj: KubernetesObject,\n): AdjudicationResult {\n return missingCarriableNamespace(capabilityNamespaces, obj)\n ? `Object does not carry a namespace but namespaces allowed by Capability are '${JSON.stringify(capabilityNamespaces)}'.`\n : null;\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// SPDX-FileCopyrightText: 2023-Present The Pepr Authors\n\nimport { AdjudicationResult, Binding } from \"../types\";\nimport { Operation } from \"../enums\";\nimport { KubernetesObject } from \"kubernetes-fluent-client\";\nimport { AdmissionRequest } from \"../common-types\";\nimport {\n adjudicateMisboundDeleteWithDeletionTimestamp,\n adjudicateMismatchedDeletionTimestamp,\n adjudicateMismatchedEvent,\n adjudicateMismatchedName,\n adjudicateMismatchedGroup,\n adjudicateMismatchedVersion,\n adjudicateMismatchedKind,\n adjudicateUnbindableNamespaces,\n adjudicateUncarryableNamespace,\n adjudicateMismatchedNamespace,\n adjudicateMismatchedLabels,\n adjudicateMismatchedAnnotations,\n adjudicateMismatchedNamespaceRegex,\n adjudicateMismatchedNameRegex,\n adjudicateCarriesIgnoredNamespace,\n adjudicateMissingCarriableNamespace,\n adjudicateMisboundNamespace,\n} from \"./adjudication\";\n\ntype Adjudicator = () => AdjudicationResult;\n\n/**\n * shouldSkipRequest determines if an admission request should be skipped based on the binding filters.\n *\n * @param binding the action binding\n * @param req the incoming request\n * @param capabilityNamespaces the namespaces allowed by capability\n * @param ignoredNamespaces the namespaces ignored by module config\n * @returns\n */\nexport function shouldSkipRequest(\n binding: Binding,\n req: AdmissionRequest,\n capabilityNamespaces: string[],\n ignoredNamespaces?: string[],\n): string {\n const obj = (req.operation === Operation.DELETE ? req.oldObject : req.object)!;\n const prefix = \"Ignoring Admission Callback:\";\n\n const adjudicators: Adjudicator[] = [\n (): AdjudicationResult => adjudicateMisboundDeleteWithDeletionTimestamp(binding),\n (): AdjudicationResult => adjudicateMismatchedDeletionTimestamp(binding, obj),\n (): AdjudicationResult => adjudicateMismatchedEvent(binding, req),\n (): AdjudicationResult => adjudicateMismatchedName(binding, obj),\n (): AdjudicationResult => adjudicateMismatchedGroup(binding, req),\n (): AdjudicationResult => adjudicateMismatchedVersion(binding, req),\n (): AdjudicationResult => adjudicateMismatchedKind(binding, req),\n (): AdjudicationResult => adjudicateUnbindableNamespaces(capabilityNamespaces, binding),\n (): AdjudicationResult => adjudicateUncarryableNamespace(capabilityNamespaces, obj),\n (): AdjudicationResult => adjudicateMismatchedNamespace(binding, obj),\n (): AdjudicationResult => adjudicateMismatchedLabels(binding, obj),\n (): AdjudicationResult => adjudicateMismatchedAnnotations(binding, obj),\n (): AdjudicationResult => adjudicateMismatchedNamespaceRegex(binding, obj),\n (): AdjudicationResult => adjudicateMismatchedNameRegex(binding, obj),\n (): AdjudicationResult => adjudicateCarriesIgnoredNamespace(ignoredNamespaces, obj),\n (): AdjudicationResult => adjudicateMissingCarriableNamespace(capabilityNamespaces, obj),\n ];\n\n for (const adjudicator of adjudicators) {\n const result = adjudicator();\n if (result) {\n return `${prefix} ${result}`;\n }\n }\n\n return \"\";\n}\n\n/**\n * filterNoMatchReason determines whether a callback should be skipped after\n * receiving an update event from the API server, based on the binding filters.\n *\n * @param binding the action binding\n * @param kubernetesObject the incoming kubernetes object\n * @param capabilityNamespaces the namespaces allowed by capability\n * @param ignoredNamespaces the namespaces ignored by module config\n */\nexport function filterNoMatchReason(\n binding: Binding,\n obj: Partial<KubernetesObject>,\n capabilityNamespaces: string[],\n ignoredNamespaces?: string[],\n): string {\n const prefix = \"Ignoring Watch Callback:\";\n\n const adjudicators: Adjudicator[] = [\n (): AdjudicationResult => adjudicateMismatchedDeletionTimestamp(binding, obj),\n (): AdjudicationResult => adjudicateMismatchedName(binding, obj),\n (): AdjudicationResult => adjudicateMisboundNamespace(binding),\n (): AdjudicationResult => adjudicateMismatchedLabels(binding, obj),\n (): AdjudicationResult => adjudicateMismatchedAnnotations(binding, obj),\n (): AdjudicationResult => adjudicateUncarryableNamespace(capabilityNamespaces, obj),\n (): AdjudicationResult => adjudicateUnbindableNamespaces(capabilityNamespaces, binding),\n (): AdjudicationResult => adjudicateMismatchedNamespace(binding, obj),\n (): AdjudicationResult => adjudicateMismatchedNamespaceRegex(binding, obj),\n (): AdjudicationResult => adjudicateMismatchedNameRegex(binding, obj),\n (): AdjudicationResult => adjudicateCarriesIgnoredNamespace(ignoredNamespaces, obj),\n (): AdjudicationResult => adjudicateMissingCarriableNamespace(capabilityNamespaces, obj),\n ];\n\n for (const adjudicator of adjudicators) {\n const result = adjudicator();\n if (result) {\n return `${prefix} ${result}`;\n }\n }\n\n return \"\";\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// SPDX-FileCopyrightText: 2023-Present The Pepr Authors\n\nimport { Operation } from \"./enums\";\nimport { KubernetesObject } from \"kubernetes-fluent-client\";\nimport { clone, mergeDeepRight } from \"ramda\";\nimport { AdmissionRequest } from \"./common-types\";\nimport { DeepPartial } from \"./common-types\";\n\n// PeprMutateRequest class for mutation request handling\nexport class PeprMutateRequest<T extends KubernetesObject> {\n Raw: T;\n #input: AdmissionRequest<T>;\n\n get PermitSideEffects(): boolean {\n return !this.#input.dryRun;\n }\n\n get IsDryRun(): boolean | undefined {\n return this.#input.dryRun;\n }\n\n get OldResource(): KubernetesObject | undefined {\n return this.#input.oldObject;\n }\n\n get Request(): AdmissionRequest<KubernetesObject> {\n return this.#input;\n }\n\n constructor(input: AdmissionRequest<T>) {\n this.#input = input;\n // If this is a DELETE operation, use the oldObject instead\n if (input.operation.toUpperCase() === Operation.DELETE) {\n this.Raw = clone(input.oldObject as T);\n } else {\n // Otherwise, use the incoming object\n this.Raw = clone(input.object);\n }\n\n if (!this.Raw) {\n throw new Error(\"Unable to load the request object into PeprRequest.Raw\");\n }\n }\n\n Merge = (obj: DeepPartial<T>): void => {\n this.Raw = mergeDeepRight(this.Raw, obj) as unknown as T;\n };\n\n SetLabel = (key: string, value: string): this => {\n const ref = this.Raw;\n ref.metadata = ref.metadata ?? {};\n ref.metadata.labels = ref.metadata.labels ?? {};\n ref.metadata.labels[key] = value;\n return this;\n };\n\n SetAnnotation = (key: string, value: string): this => {\n const ref = this.Raw;\n ref.metadata = ref.metadata ?? {};\n ref.metadata.annotations = ref.metadata.annotations ?? {};\n ref.metadata.annotations[key] = value;\n return this;\n };\n\n RemoveLabel = (key: string): this => {\n if (this.Raw.metadata?.labels?.[key]) {\n delete this.Raw.metadata.labels[key];\n }\n return this;\n };\n\n RemoveAnnotation = (key: string): this => {\n if (this.Raw.metadata?.annotations?.[key]) {\n delete this.Raw.metadata.annotations[key];\n }\n return this;\n };\n\n HasLabel = (key: string): boolean => {\n return this.Raw.metadata?.labels?.[key] !== undefined;\n };\n\n HasAnnotation = (key: string): boolean => {\n return this.Raw.metadata?.annotations?.[key] !== undefined;\n };\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// SPDX-FileCopyrightText: 2023-Present The Pepr Authors\n\nimport Log from \"./telemetry/logger\";\n\n/** Test if a string is ascii or not */\nexport const isAscii: RegExp = /^[\\s\\x20-\\x7E]*$/;\n\n/**\n * Encode all ascii values in a map to base64\n * @param obj The object to encode\n * @param skip A list of keys to skip encoding\n */\nexport function convertToBase64Map(obj: { data?: Record<string, string> }, skip: string[]): void {\n obj.data = obj.data ?? {};\n for (const key in obj.data) {\n const value = obj.data[key];\n // Only encode ascii values\n obj.data[key] = skip.includes(key) ? value : base64Encode(value);\n }\n}\n\n/**\n * Decode all ascii values in a map from base64 to utf-8\n * @param obj The object to decode\n * @returns A list of keys that were skipped\n */\nexport function convertFromBase64Map(obj: { data?: Record<string, string> }): string[] {\n const skip: string[] = [];\n\n obj.data = obj.data ?? {};\n for (const key in obj.data) {\n if (obj.data[key] === undefined) {\n obj.data[key] = \"\";\n } else {\n const decoded = base64Decode(obj.data[key]);\n if (isAscii.test(decoded)) {\n // Only decode ascii values\n obj.data[key] = decoded;\n } else {\n skip.push(key);\n }\n }\n }\n Log.debug(`Non-ascii data detected in keys: ${skip}, skipping automatic base64 decoding`);\n return skip;\n}\n\n/** Decode a base64 string */\nexport function base64Decode(data: string): string {\n return Buffer.from(data, \"base64\").toString(\"utf-8\");\n}\n\n/** Encode a string to base64 */\nexport function base64Encode(data: string): string {\n return Buffer.from(data).toString(\"base64\");\n}\n", "export enum RbacMode {\n SCOPED = \"scoped\",\n ADMIN = \"admin\",\n}\nexport enum OnError {\n AUDIT = \"audit\",\n IGNORE = \"ignore\",\n REJECT = \"reject\",\n}\n\nexport const UUID_LENGTH_LIMIT = 36;\n", "// SPDX-License-Identifier: Apache-2.0\n// SPDX-FileCopyrightText: 2023-Present The Pepr Authors\n\nexport function resolveIgnoreNamespaces(ignoredNSConfig: string[] = []): string[] {\n const ignoredNSEnv = process.env.PEPR_ADDITIONAL_IGNORED_NAMESPACES;\n if (!ignoredNSEnv) {\n return ignoredNSConfig;\n }\n\n const namespaces = ignoredNSEnv.split(\",\").map(ns => ns.trim());\n\n // add alwaysIgnore.namespaces to the list\n if (ignoredNSConfig) {\n namespaces.push(...ignoredNSConfig);\n }\n return namespaces.filter(ns => ns.length > 0);\n}\n", "import { convertFromBase64Map, convertToBase64Map } from \"../utils\";\nimport { kind, KubernetesObject } from \"kubernetes-fluent-client\";\nimport { PeprMutateRequest } from \"../mutate-request\";\nimport { clone } from \"ramda\";\n\nexport function decodeData(wrapped: PeprMutateRequest<KubernetesObject>): {\n skipped: string[];\n wrapped: PeprMutateRequest<KubernetesObject>;\n} {\n let skipped: string[] = [];\n\n const isSecret = wrapped.Request.kind.version === \"v1\" && wrapped.Request.kind.kind === \"Secret\";\n if (isSecret) {\n // convertFromBase64Map modifies it's arg rather than returing a mod'ed copy (ye olde side-effect special, blerg)\n skipped = convertFromBase64Map(wrapped.Raw as unknown as kind.Secret);\n }\n\n return { skipped, wrapped };\n}\n\nexport function reencodeData(\n wrapped: PeprMutateRequest<KubernetesObject>,\n skipped: string[],\n): KubernetesObject {\n const transformed = clone(wrapped.Raw);\n\n const isSecret = wrapped.Request.kind.version === \"v1\" && wrapped.Request.kind.kind === \"Secret\";\n if (isSecret) {\n // convertToBase64Map modifies it's arg rather than returing a mod'ed copy (ye olde side-effect special, blerg)\n convertToBase64Map(transformed as unknown as kind.Secret, skipped);\n }\n\n return transformed;\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// SPDX-FileCopyrightText: 2023-Present The Pepr Authors\n\n/* eslint-disable class-methods-use-this */\n\nimport { KubernetesObject } from \"kubernetes-fluent-client\";\n\nimport { clone } from \"ramda\";\nimport { AdmissionRequest, ValidateActionResponse } from \"./common-types\";\nimport { Operation } from \"./enums\";\n\n/**\n * The RequestWrapper class provides methods to modify Kubernetes objects in the context\n * of a mutating webhook request.\n */\nexport class PeprValidateRequest<T extends KubernetesObject> {\n Raw: T;\n\n #input: AdmissionRequest<T>;\n\n /**\n * Provides access to the old resource in the request if available.\n * @returns The old Kubernetes resource object or null if not available.\n */\n get OldResource(): KubernetesObject | undefined {\n return this.#input.oldObject;\n }\n\n /**\n * Provides access to the request object.\n * @returns The request object containing the Kubernetes resource.\n */\n get Request(): AdmissionRequest<KubernetesObject> {\n return this.#input;\n }\n\n /**\n * Creates a new instance of the Action class.\n * @param input - The request object containing the Kubernetes resource to modify.\n */\n constructor(input: AdmissionRequest<T>) {\n this.#input = input;\n\n // If this is a DELETE operation, use the oldObject instead\n if (input.operation.toUpperCase() === Operation.DELETE) {\n this.Raw = clone(input.oldObject as T);\n } else {\n // Otherwise, use the incoming object\n this.Raw = clone(input.object);\n }\n\n if (!this.Raw) {\n throw new Error(\"unable to load the request object into PeprRequest.Raw\");\n }\n }\n\n /**\n * Check if a label exists on the Kubernetes resource.\n *\n * @param key the label key to check\n * @returns\n */\n HasLabel = (key: string): boolean => {\n return this.Raw.metadata?.labels?.[key] !== undefined;\n };\n\n /**\n * Check if an annotation exists on the Kubernetes resource.\n *\n * @param key the annotation key to check\n * @returns\n */\n HasAnnotation = (key: string): boolean => {\n return this.Raw.metadata?.annotations?.[key] !== undefined;\n };\n\n /**\n * Create a validation response that allows the request.\n *\n * @returns The validation response.\n */\n Approve = (warnings?: string[]): ValidateActionResponse => {\n return {\n allowed: true,\n warnings,\n };\n };\n\n /**\n * Create a validation response that denies the request.\n *\n * @param statusMessage Optional status message to return to the user.\n * @param statusCode Optional status code to return to the user.\n * @returns The validation response.\n */\n Deny = (\n statusMessage?: string,\n statusCode?: number,\n warnings?: string[],\n ): ValidateActionResponse => {\n return {\n allowed: false,\n statusCode,\n statusMessage,\n warnings,\n };\n };\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// SPDX-FileCopyrightText: 2023-Present The Pepr Authors\n\nimport { kind, KubernetesObject } from \"kubernetes-fluent-client\";\nimport { Capability } from \"../core/capability\";\nimport { shouldSkipRequest } from \"../filter/filter\";\nimport { ValidateResponse } from \"../k8s\";\nimport { Binding } from \"../types\";\nimport Log from \"../telemetry/logger\";\nimport { convertFromBase64Map } from \"../utils\";\nimport { PeprValidateRequest } from \"../validate-request\";\nimport { ModuleConfig } from \"../types\";\nimport { resolveIgnoreNamespaces } from \"../assets/ignoredNamespaces\";\nimport { MeasureWebhookTimeout } from \"../telemetry/webhookTimeouts\";\nimport { WebhookType } from \"../enums\";\nimport { AdmissionRequest } from \"../common-types\";\n\nexport async function processRequest(\n binding: Binding,\n actionMetadata: Record<string, string>,\n peprValidateRequest: PeprValidateRequest<KubernetesObject>,\n): Promise<ValidateResponse> {\n const label = binding.validateCallback!.name;\n Log.info(actionMetadata, `Processing validation action (${label})`);\n\n const valResp: ValidateResponse = {\n uid: peprValidateRequest.Request.uid,\n allowed: true, // Assume it's allowed until a validation check fails\n };\n\n try {\n // Run the validation callback, if it fails set allowed to false\n const callbackResp = await binding.validateCallback!(peprValidateRequest);\n valResp.allowed = callbackResp.allowed;\n\n // If the validation callback returned a status code or message, set it in the Response\n if (callbackResp.statusCode || callbackResp.statusMessage) {\n valResp.status = {\n code: callbackResp.statusCode || 400,\n message:\n callbackResp.statusMessage ||\n `Validation failed for ${peprValidateRequest.Request.kind.kind.toLowerCase()}/${peprValidateRequest.Request.name}${peprValidateRequest.Request.namespace ? ` in ${peprValidateRequest.Request.namespace} namespace.` : \"\"}`,\n };\n }\n\n // Transfer any warnings from the callback response to the validation response\n if (callbackResp.warnings && callbackResp.warnings.length > 0) {\n valResp.warnings = callbackResp.warnings;\n }\n\n Log.info(\n actionMetadata,\n `Validation action complete (${label}): ${callbackResp.allowed ? \"allowed\" : \"denied\"}`,\n );\n return valResp;\n } catch (e) {\n // If any validation throws an error, note the failure in the Response\n Log.error(actionMetadata, `Action failed: ${JSON.stringify(e)}`);\n valResp.allowed = false;\n valResp.status = {\n code: 500,\n message: `Action failed with error: ${JSON.stringify(e)}`,\n };\n return valResp;\n }\n}\n\nexport async function validateProcessor(\n config: ModuleConfig,\n capabilities: Capability[],\n req: AdmissionRequest,\n reqMetadata: Record<string, string>,\n): Promise<ValidateResponse[]> {\n const webhookTimer = new MeasureWebhookTimeout(WebhookType.VALIDATE);\n webhookTimer.start(config.webhookTimeout);\n const wrapped = new PeprValidateRequest(req);\n const response: ValidateResponse[] = [];\n\n // If the resource is a secret, decode the data\n if (req.kind.version === \"v1\" && req.kind.kind === \"Secret\") {\n convertFromBase64Map(wrapped.Raw as unknown as kind.Secret);\n }\n\n Log.info(reqMetadata, `Processing validation request`);\n\n for (const { name, bindings, namespaces } of capabilities) {\n const actionMetadata = { ...reqMetadata, name };\n\n for (const binding of bindings) {\n // Skip this action if it's not a validation action\n if (!binding.validateCallback) {\n continue;\n }\n\n // Continue to the next action without doing anything if this one should be skipped\n const shouldSkip = shouldSkipRequest(\n binding,\n req,\n namespaces,\n resolveIgnoreNamespaces(\n config?.alwaysIgnore?.namespaces?.length\n ? config?.alwaysIgnore?.namespaces\n : config?.admission?.alwaysIgnore?.namespaces,\n ),\n );\n if (shouldSkip !== \"\") {\n Log.debug(shouldSkip);\n continue;\n }\n\n const resp = await processRequest(binding, actionMetadata, wrapped);\n response.push(resp);\n }\n }\n webhookTimer.stop();\n return response;\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// SPDX-FileCopyrightText: 2023-Present The Pepr Authors\n\nimport { Operation } from \"fast-json-patch\";\nimport { K8s } from \"kubernetes-fluent-client\";\nimport { startsWith } from \"ramda\";\n\nimport { Capability } from \"../core/capability\";\nimport { Store } from \"../k8s\";\nimport Log, { redactedPatch, redactedStore } from \"../telemetry/logger\";\nimport { DataOp, DataSender, DataStore, Storage } from \"../core/storage\";\nimport { fillStoreCache, sendUpdatesAndFlushCache } from \"./storeCache\";\nimport { migrateAndSetupWatch } from \"./migrateStore\";\n\nconst namespace = \"pepr-system\";\nconst debounceBackoffReceive = 1000;\nconst debounceBackoffSend = 4000;\n\nexport class StoreController {\n #name: string;\n #stores: Record<string, Storage> = {};\n #sendDebounce: NodeJS.Timeout | undefined;\n #onReady?: () => void;\n\n constructor(capabilities: Capability[], name: string, onReady?: () => void) {\n this.#onReady = onReady;\n\n this.#name = name;\n\n const setStorageInstance = (registrationFunction: () => Storage, name: string): void => {\n const scheduleStore = registrationFunction();\n\n // Bind the store sender to the capability\n scheduleStore.registerSender(this.#send(name));\n\n // Store the storage instance\n this.#stores[name] = scheduleStore;\n };\n\n if (name.includes(\"schedule\")) {\n // Establish the store for each capability\n for (const { name, registerScheduleStore, hasSchedule } of capabilities) {\n if (hasSchedule === true) {\n // Register the scheduleStore with the capability\n setStorageInstance(registerScheduleStore, name);\n }\n }\n } else {\n // Establish the store for each capability\n for (const { name, registerStore } of capabilities) {\n setStorageInstance(registerStore, name);\n }\n }\n\n setTimeout(\n () =>\n K8s(Store)\n .InNamespace(namespace)\n .Get(this.#name)\n .then(\n async (store: Store) =>\n await migrateAndSetupWatch({\n name,\n namespace,\n store,\n stores: this.#stores,\n setupWatch: this.#setupWatch,\n }),\n )\n .catch(this.#createStoreResource),\n Math.random() * 3000, // Add a jitter to the Store creation to avoid collisions\n );\n }\n\n #setupWatch = (): void => {\n const watcher = K8s(Store, { name: this.#name, namespace }).Watch(this.#receive);\n watcher.start().catch(e => Log.error(e, \"Error starting Pepr store watch\"));\n };\n\n #receive = (store: Store): void => {\n Log.debug(redactedStore(store), \"Pepr Store update\");\n\n // Wrap the update in a debounced function\n const debounced = (): void => {\n // Base64 decode the data\n const data: DataStore = store.data || {};\n\n // Loop over each stored capability\n for (const name of Object.keys(this.#stores)) {\n // Get the prefix offset for the keys\n const offset = `${name}-`.length;\n\n // Get any keys that match the capability name prefix\n const filtered: DataStore = {};\n\n // Loop over each key in the secret\n for (const key of Object.keys(data)) {\n // Match on the capability name as a prefix\n if (startsWith(name, key)) {\n // Strip the prefix and store the value\n filtered[key.slice(offset)] = data[key];\n }\n }\n\n // Send the data to the receiver callback\n this.#stores[name].receive(filtered);\n }\n\n // Call the onReady callback if this is the first time the secret has been read\n if (this.#onReady) {\n this.#onReady();\n this.#onReady = undefined;\n }\n };\n\n // Debounce the update to 1 second to avoid multiple rapid calls\n clearTimeout(this.#sendDebounce);\n this.#sendDebounce = setTimeout(debounced, this.#onReady ? 0 : debounceBackoffReceive);\n };\n\n #send = (capabilityName: string): DataSender => {\n let storeCache: Record<string, Operation> = {};\n\n // Create a sender function for the capability to add/remove data from the store\n const sender: DataSender = async (op: DataOp, key: string[], value?: string) => {\n storeCache = fillStoreCache(storeCache, capabilityName, op, { key, value });\n };\n\n // Send any cached updates every debounceBackoff milliseconds\n setInterval(() => {\n if (Object.keys(storeCache).length > 0) {\n Log.debug(redactedPatch(storeCache), \"Sending updates to Pepr store\");\n void sendUpdatesAndFlushCache(storeCache, namespace, this.#name);\n }\n }, debounceBackoffSend);\n\n return sender;\n };\n\n #createStoreResource = async (e: unknown): Promise<void> => {\n Log.debug(`Pepr store not found, creating...`);\n Log.debug(e);\n\n try {\n await K8s(Store).Apply({\n metadata: {\n name: this.#name,\n namespace,\n labels: {\n \"pepr.dev-cacheID\": `${Date.now()}`,\n },\n },\n data: {\n // JSON Patch will die if the data is empty, so we need to add a placeholder\n __pepr_do_not_delete__: \"k-thx-bye\",\n },\n });\n\n // Now that the resource exists, setup the watch\n this.#setupWatch();\n } catch (err) {\n Log.error(err, \"Failed to create Pepr store\");\n }\n };\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// SPDX-FileCopyrightText: 2023-Present The Pepr Authors\n\nimport { GenericKind, RegisterKind } from \"kubernetes-fluent-client\";\n\n/**\n * PeprStore for internal use by Pepr. This is used to store arbitrary data in the cluster.\n */\nexport class Store extends GenericKind {\n declare data: {\n [key: string]: string;\n };\n}\n\nexport const peprStoreGVK = {\n kind: \"PeprStore\",\n version: \"v1\",\n group: \"pepr.dev\",\n};\n\nRegisterKind(Store, peprStoreGVK);\n\nexport interface MutateResponse {\n /** UID is an identifier for the individual request/response. This must be copied over from the corresponding AdmissionRequest. */\n uid: string;\n\n /** Allowed indicates whether or not the admission request was permitted. */\n allowed: boolean;\n\n /** Result contains extra details into why an admission request was denied. This field IS NOT consulted in any way if \"Allowed\" is \"true\". */\n result?: string;\n\n /** The patch body. Currently we only support \"JSONPatch\" which implements RFC 6902. */\n patch?: string;\n\n /** The type of Patch. Currently we only allow \"JSONPatch\". */\n patchType?: \"JSONPatch\";\n\n /**\n * AuditAnnotations is an unstructured key value map set by remote admission controller (e.g. error=image-blacklisted).\n *\n * See https://kubernetes.io/docs/reference/labels-annotations-taints/audit-annotations/ for more information\n */\n auditAnnotations?: {\n [key: string]: string;\n };\n\n /** warnings is a list of warning messages to return to the requesting API client. */\n warnings?: string[];\n}\n\nexport interface ValidateResponse extends MutateResponse {\n /** Status contains extra details into why an admission request was denied. This field IS NOT consulted in any way if \"Allowed\" is \"true\". */\n status?: {\n /** A machine-readable description of why this operation is in the\n \"Failure\" status. If this value is empty there is no information available. */\n code: number;\n\n /** A human-readable description of the status of this operation. */\n message: string;\n };\n}\n\nexport type WebhookIgnore = {\n /**\n * List of Kubernetes namespaces to always ignore.\n * Any resources in these namespaces will be ignored by Pepr.\n *\n * Note: `kube-system` and `pepr-system` are always ignored.\n */\n namespaces?: string[];\n};\n", "import { DataOp } from \"../core/storage\";\nimport Log from \"../telemetry/logger\";\nimport { K8s } from \"kubernetes-fluent-client\";\nimport { Store } from \"../k8s\";\nimport { StatusCodes } from \"http-status-codes\";\nimport { Operation } from \"fast-json-patch\";\n\nexport const sendUpdatesAndFlushCache = async (\n cache: Record<string, Operation>,\n namespace: string,\n name: string,\n): Promise<Record<string, Operation>> => {\n const indexes = Object.keys(cache);\n const payload = Object.values(cache);\n\n try {\n if (payload.length > 0) {\n await K8s(Store, { namespace, name }).Patch(updateCacheID(payload)); // Send patch to cluster\n Object.keys(cache).forEach(key => delete cache[key]);\n }\n } catch (err) {\n Log.error(err, \"Pepr store update failure\");\n\n if (err.status === StatusCodes.UNPROCESSABLE_ENTITY) {\n Object.keys(cache).forEach(key => delete cache[key]);\n } else {\n indexes.forEach(index => {\n cache[index] = payload[Number(index)]; // On failure to update, re-add the operations to the cache to be retried\n });\n }\n }\n return cache;\n};\n\ntype CacheItem = {\n key: string[];\n value?: string;\n version?: string;\n};\n\nexport const fillStoreCache = (\n cache: Record<string, Operation>,\n capabilityName: string,\n op: DataOp,\n cacheItem: CacheItem,\n): Record<string, Operation> => {\n const path = [`/data/${capabilityName}`, cacheItem.version, cacheItem.key] // adjust the path, see ADR-0008\n .filter(str => str !== \"\" && str !== undefined)\n .join(\"-\");\n if (op === \"add\") {\n const value = cacheItem.value || \"\";\n const cacheIdx = [op, path, value].join(\":\");\n\n // Add the operation to the cache\n cache[cacheIdx] = { op, path, value };\n } else if (op === \"remove\") {\n if (cacheItem.key.length < 1) {\n throw new Error(`Key is required for REMOVE operation`);\n }\n const cacheIndex = [op, path].join(\":\");\n // Add the operation to the cache\n cache[cacheIndex] = { op, path };\n } else {\n throw new Error(`Unsupported operation: ${op}`);\n }\n return cache;\n};\n\nexport function updateCacheID(payload: Operation[]): Operation[] {\n payload.push({\n op: \"replace\",\n path: \"/metadata/labels/pepr.dev-cacheID\",\n value: `${Date.now()}`,\n });\n return payload;\n}\n", "import { DataStore, Storage } from \"../core/storage\";\nimport { startsWith } from \"ramda\";\nimport Log, { redactedStore } from \"../telemetry/logger\";\nimport { K8s } from \"kubernetes-fluent-client\";\nimport { Store } from \"../k8s\";\nimport { Operation } from \"fast-json-patch\";\nimport { fillStoreCache, sendUpdatesAndFlushCache } from \"./storeCache\";\n\nexport interface StoreMigration {\n name: string;\n namespace: string;\n store: Store;\n stores: Record<string, Storage>;\n setupWatch: () => void;\n}\n\nexport async function migrateAndSetupWatch(storeData: StoreMigration): Promise<void> {\n const { store, namespace, name, stores, setupWatch } = storeData;\n\n Log.debug(redactedStore(store), \"Pepr Store migration\");\n // Add cacheID label to store\n await K8s(Store, { namespace, name }).Patch([\n {\n op: \"add\",\n path: \"/metadata/labels/pepr.dev-cacheID\",\n value: `${Date.now()}`,\n },\n ]);\n\n const data: DataStore = store.data;\n let storeCache: Record<string, Operation> = {};\n\n for (const name of Object.keys(stores)) {\n // Get the prefix offset for the keys\n const offset = `${name}-`.length;\n\n // Loop over each key in the store\n for (const key of Object.keys(data)) {\n // Match on the capability name as a prefix for non v2 keys\n if (startsWith(name, key) && !startsWith(`${name}-v2`, key)) {\n // populate migrate cache\n storeCache = fillStoreCache(storeCache, name, \"remove\", {\n key: [key.slice(offset)],\n value: data[key],\n });\n storeCache = fillStoreCache(storeCache, name, \"add\", {\n key: [key.slice(offset)],\n value: data[key],\n version: \"v2\",\n });\n }\n }\n }\n storeCache = await sendUpdatesAndFlushCache(storeCache, namespace, name);\n setupWatch();\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// SPDX-FileCopyrightText: 2023-Present The Pepr Authors\n\nimport { AdmissionRequest } from \"../common-types\";\nimport { MutateResponse, ValidateResponse } from \"../k8s\";\nimport { ResponseItem } from \"../types\";\n\nexport interface KubeAdmissionReview {\n apiVersion: string;\n kind: string;\n response: ValidateResponse[] | MutateResponse | ResponseItem;\n}\n\nexport function karForMutate(mr: MutateResponse): KubeAdmissionReview {\n return {\n apiVersion: \"admission.k8s.io/v1\",\n kind: \"AdmissionReview\",\n response: mr,\n };\n}\n\nexport function karForValidate(ar: AdmissionRequest, vr: ValidateResponse[]): KubeAdmissionReview {\n const isAllowed = vr.filter(r => !r.allowed).length === 0;\n\n // Collect all warnings from the ValidateResponse array\n const warnings = vr.reduce<string[]>((acc, curr) => {\n if (curr.warnings && curr.warnings.length > 0) {\n return [...acc, ...curr.warnings];\n }\n return acc;\n }, []);\n\n const resp: ValidateResponse =\n vr.length === 0\n ? {\n uid: ar.uid,\n allowed: true,\n status: { code: 200, message: \"no in-scope validations -- allowed!\" },\n warnings: warnings.length > 0 ? warnings : undefined,\n }\n : {\n uid: vr[0].uid,\n allowed: isAllowed,\n status: {\n code: isAllowed ? 200 : 422,\n message: vr\n .filter(rl => !rl.allowed)\n .map(curr => curr.status?.message)\n .join(\"; \"),\n },\n warnings: warnings.length > 0 ? warnings : undefined,\n };\n return {\n apiVersion: \"admission.k8s.io/v1\",\n kind: \"AdmissionReview\",\n response: resp,\n };\n}\n", "export interface FeatureMetadata {\n name: string;\n description: string;\n defaultValue: FeatureValue;\n}\n\nexport interface FeatureInfo {\n key: string;\n metadata: FeatureMetadata;\n}\n// All known feature flags with their metadata\nexport const FeatureFlags: Record<string, FeatureInfo> = {\n REFERENCE_FLAG: {\n key: \"reference_flag\",\n metadata: {\n name: \"Reference Flag\",\n description: \"A feature flag to show intended usage.\",\n defaultValue: false,\n },\n },\n};\n\nexport type FeatureValue = string | boolean | number;\n", "// SPDX-License-Identifier: Apache-2.0\n// SPDX-FileCopyrightText: 2023-Present The Pepr Authors\n\nimport { FeatureFlags, FeatureValue } from \"./FeatureFlags\";\n\nexport class FeatureStore {\n private featureFlagLimit: number = 4;\n private features: Record<string, FeatureValue> = {};\n\n private addFeature(key: string, value: string): void {\n if (!key || value === undefined || value === \"\") return;\n\n const validKeys = Object.values(FeatureFlags)\n .filter(f => f?.key)\n .map(f => f.key);\n if (!validKeys.includes(key)) {\n throw new Error(`Unknown feature flag: ${key}`);\n }\n\n const lowerValue = value.toLowerCase();\n if (lowerValue === \"true\") {\n this.features[key] = true;\n } else if (lowerValue === \"false\") {\n this.features[key] = false;\n } else if (!isNaN(Number(value))) {\n this.features[key] = Number(value);\n } else {\n this.features[key] = value;\n }\n }\n\n get<T extends FeatureValue>(key: string): T {\n if (!Object.values(FeatureFlags).some(f => f?.key === key)) {\n throw new Error(`Unknown feature flag: ${key}`);\n }\n\n if (!(key in this.features)) {\n throw new Error(`Feature flag '${key}' exists but has not been set`);\n }\n\n return this.features[key] as T;\n }\n\n getAll(): Record<string, FeatureValue> {\n return { ...this.features };\n }\n\n initialize(featuresStr?: string, env: Record<string, string | undefined> = process.env): void {\n Object.keys(env)\n .filter(key => key.startsWith(\"PEPR_FEATURE_\"))\n .forEach(key => {\n this.addFeature(key.replace(\"PEPR_FEATURE_\", \"\").toLowerCase(), env[key] || \"\");\n });\n\n if (featuresStr) {\n featuresStr\n .split(\",\")\n .map(feature => feature.split(\"=\"))\n .filter(parts => parts.length === 2)\n .forEach(([key, value]) => {\n this.addFeature(key.trim(), value.trim());\n });\n }\n\n this.applyDefaultValues();\n this.validateFeatureCount();\n }\n\n private applyDefaultValues(): void {\n Object.values(FeatureFlags)\n .filter(\n feature =>\n feature?.key &&\n feature?.metadata?.defaultValue !== undefined &&\n !(feature.key in this.features),\n )\n .forEach(feature => {\n this.features[feature.key] = feature.metadata.defaultValue;\n });\n }\n\n validateFeatureCount(): void {\n const featureCount = Object.keys(this.features).length;\n if (featureCount > this.featureFlagLimit) {\n throw new Error(\n `Too many feature flags active: ${featureCount} (maximum: ${this.featureFlagLimit}). Use of more than ${this.featureFlagLimit} feature flags is not supported.`,\n );\n }\n }\n}\n\nexport const featureFlagStore = new FeatureStore();\n", "// SPDX-License-Identifier: Apache-2.0\n// SPDX-FileCopyrightText: 2023-Present The Pepr Authors\n\nimport { OnError } from \"../cli/init/enums\";\n\nexport const ErrorList = Object.values(OnError) as string[];\n/**\n * Validate the error or throw an error\n * @param error\n */\nexport function ValidateError(error: string = \"\"): void {\n if (!ErrorList.includes(error)) {\n throw new Error(`Invalid error: ${error}. Must be one of: ${ErrorList.join(\", \")}`);\n }\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// SPDX-FileCopyrightText: 2023-Present The Pepr Authors\nimport Log from \"../telemetry/logger\";\nimport { Binding } from \"../types\";\nimport { Capability } from \"../core/capability\";\nimport { Event } from \"../enums\";\nimport {\n K8s,\n KubernetesObject,\n WatchCfg,\n WatchEvent,\n GenericClass,\n} from \"kubernetes-fluent-client\";\nimport { Queue } from \"../core/queue\";\nimport { WatcherType } from \"kubernetes-fluent-client/dist/fluent/types\";\nimport { WatchPhase } from \"kubernetes-fluent-client/dist/fluent/shared-types\";\nimport { KubernetesListObject } from \"kubernetes-fluent-client/dist/types\";\nimport { filterNoMatchReason } from \"../filter/filter\";\nimport { metricsCollector, MetricsCollectorInstance } from \"../telemetry/metrics\";\nimport { removeFinalizer } from \"../finalizer\";\n\n// stores Queue instances\nconst queues: Record<string, Queue<KubernetesObject>> = {};\n\n/**\n * Get the key for an entry in the queues\n *\n * @param obj The object to derive a key from\n * @returns The key to a Queue in the list of queues\n */\nexport function queueKey(obj: KubernetesObject): string {\n const options = [\"kind\", \"kindNs\", \"kindNsName\", \"global\"];\n const d3fault = \"kindNsName\";\n\n let strat = process.env.PEPR_RECONCILE_STRATEGY || d3fault;\n strat = options.includes(strat) ? strat : d3fault;\n\n const ns = obj.metadata?.namespace ?? \"cluster-scoped\";\n const kind = obj.kind ?? \"UnknownKind\";\n const name = obj.metadata?.name ?? \"Unnamed\";\n\n const lookup: Record<string, string> = {\n kind: `${kind}`,\n kindNs: `${kind}/${ns}`,\n kindNsName: `${kind}/${ns}/${name}`,\n global: \"global\",\n };\n return lookup[strat];\n}\n\nexport function getOrCreateQueue(obj: KubernetesObject): Queue<KubernetesObject> {\n const key = queueKey(obj);\n if (!queues[key]) {\n queues[key] = new Queue<KubernetesObject>(key);\n }\n return queues[key];\n}\n\n// Watch configuration\nconst watchCfg: WatchCfg = {\n resyncFailureMax: process.env.PEPR_RESYNC_FAILURE_MAX\n ? parseInt(process.env.PEPR_RESYNC_FAILURE_MAX, 10)\n : 5,\n resyncDelaySec: process.env.PEPR_RESYNC_DELAY_SECONDS\n ? parseInt(process.env.PEPR_RESYNC_DELAY_SECONDS, 10)\n : 5,\n lastSeenLimitSeconds: process.env.PEPR_LAST_SEEN_LIMIT_SECONDS\n ? parseInt(process.env.PEPR_LAST_SEEN_LIMIT_SECONDS, 10)\n : 300,\n relistIntervalSec: process.env.PEPR_RELIST_INTERVAL_SECONDS\n ? parseInt(process.env.PEPR_RELIST_INTERVAL_SECONDS, 10)\n : 600,\n};\n\n// Map the event to the watch phase\nconst eventToPhaseMap = {\n [Event.CREATE]: [WatchPhase.Added],\n [Event.UPDATE]: [WatchPhase.Modified],\n [Event.CREATE_OR_UPDATE]: [WatchPhase.Added, WatchPhase.Modified],\n [Event.DELETE]: [WatchPhase.Deleted],\n [Event.ANY]: [WatchPhase.Added, WatchPhase.Modified, WatchPhase.Deleted],\n};\n\n/**\n * Entrypoint for setting up watches for all capabilities\n *\n * @param capabilities The capabilities to load watches for\n */\nexport function setupWatch(capabilities: Capability[], ignoredNamespaces?: string[]): void {\n for (const capability of capabilities) {\n for (const binding of capability.bindings.filter(b => b.isWatch)) {\n runBinding(binding, capability.namespaces, ignoredNamespaces);\n }\n }\n}\n\n/**\n * Setup a watch for a binding\n *\n * @param binding the binding to watch\n * @param capabilityNamespaces list of namespaces to filter on\n */\nexport async function runBinding(\n binding: Binding,\n capabilityNamespaces: string[],\n ignoredNamespaces?: string[],\n): Promise<void> {\n // Get the phases to match, fallback to any\n const phaseMatch: WatchPhase[] = eventToPhaseMap[binding.event] || eventToPhaseMap[Event.ANY];\n\n // The watch callback is run when an object is received or dequeued\n Log.debug({ watchCfg }, \"Effective WatchConfig\");\n\n const watchCallback = async (\n kubernetesObject: KubernetesObject,\n phase: WatchPhase,\n ): Promise<void> => {\n // First, filter the object based on the phase\n if (phaseMatch.includes(phase)) {\n try {\n // Then, check if the object matches the filter\n const filterMatch = filterNoMatchReason(\n binding,\n kubernetesObject,\n capabilityNamespaces,\n ignoredNamespaces,\n );\n if (filterMatch !== \"\") {\n Log.debug(filterMatch);\n return;\n }\n if (binding.isFinalize) {\n await handleFinalizerRemoval(kubernetesObject);\n } else {\n await binding.watchCallback?.(kubernetesObject, phase);\n }\n } catch (e) {\n // Errors in the watch callback should not crash the controller\n Log.error(e, \"Error executing watch callback\");\n }\n }\n };\n\n const handleFinalizerRemoval = async (kubernetesObject: KubernetesObject): Promise<void> => {\n if (!kubernetesObject.metadata?.deletionTimestamp) {\n return;\n }\n let shouldRemoveFinalizer: boolean | void | undefined = true;\n try {\n shouldRemoveFinalizer = await binding.finalizeCallback?.(kubernetesObject);\n\n // if not opt'ed out of / if in error state, remove pepr finalizer\n } finally {\n const peprFinal = \"pepr.dev/finalizer\";\n const meta = kubernetesObject.metadata!;\n const resource = `${meta.namespace || \"ClusterScoped\"}/${meta.name}`;\n\n // [ true, void, undefined ] SHOULD remove finalizer\n // [ false ] should NOT remove finalizer\n if (shouldRemoveFinalizer === false) {\n Log.debug(\n { obj: kubernetesObject },\n `Skipping removal of finalizer '${peprFinal}' from '${resource}'`,\n );\n } else {\n await removeFinalizer(binding, kubernetesObject);\n }\n }\n };\n\n // Setup the resource watch\n const watcher = K8s(binding.model, { ...binding.filters, kindOverride: binding.kind }).Watch(\n async (obj, phase) => {\n Log.debug(obj, `Watch event ${phase} received`);\n\n if (binding.isQueue) {\n const queue = getOrCreateQueue(obj);\n await queue.enqueue(obj, phase, watchCallback);\n } else {\n await watchCallback(obj, phase);\n }\n },\n watchCfg,\n );\n\n // Register event handlers\n try {\n registerWatchEventHandlers(watcher, logEvent, metricsCollector);\n } catch (err) {\n throw new Error(\n \"WatchEventHandler Registration Error: Unable to register event watch handler.\",\n { cause: err },\n );\n }\n\n // Start the watch\n try {\n await watcher.start();\n } catch (err) {\n throw new Error(\"WatchStart Error: Unable to start watch.\", { cause: err });\n }\n}\n\nexport function logEvent(event: WatchEvent, message: string = \"\", obj?: KubernetesObject): void {\n const logMessage = `Watch event ${event} received${message ? `. ${message}.` : \".\"}`;\n if (obj) {\n Log.debug(obj, logMessage);\n } else {\n Log.debug(logMessage);\n }\n}\n\nexport type WatchEventArgs<K extends WatchEvent, T extends GenericClass> = {\n [WatchEvent.LIST]: KubernetesListObject<InstanceType<T>>;\n [WatchEvent.RECONNECT]: number;\n [WatchEvent.CACHE_MISS]: string;\n [WatchEvent.INIT_CACHE_MISS]: string;\n [WatchEvent.GIVE_UP]: Error;\n [WatchEvent.ABORT]: Error;\n [WatchEvent.OLD_RESOURCE_VERSION]: string;\n [WatchEvent.NETWORK_ERROR]: Error;\n [WatchEvent.LIST_ERROR]: Error;\n [WatchEvent.DATA_ERROR]: Error;\n [WatchEvent.CONNECT]: string;\n [WatchEvent.RECONNECT_PENDING]: undefined;\n [WatchEvent.DATA]: undefined;\n [WatchEvent.INC_RESYNC_FAILURE_COUNT]: number;\n}[K];\n\nexport type LogEventFunction = (event: WatchEvent, message?: string) => void;\nexport function registerWatchEventHandlers(\n watcher: WatcherType<GenericClass>,\n logEvent: LogEventFunction,\n metricsCollector: MetricsCollectorInstance,\n): void {\n const eventHandlers: {\n [K in WatchEvent]?: (arg: WatchEventArgs<K, GenericClass>) => void;\n } = {\n [WatchEvent.DATA]: () => null,\n [WatchEvent.GIVE_UP]: err => {\n // If failure continues, log and exit\n logEvent(WatchEvent.GIVE_UP, err.message);\n throw new Error(\n \"WatchEvent GiveUp Error: The watch has failed to start after several attempts.\",\n { cause: err },\n );\n },\n [WatchEvent.CONNECT]: url => logEvent(WatchEvent.CONNECT, url),\n [WatchEvent.DATA_ERROR]: err => logEvent(WatchEvent.DATA_ERROR, err.message),\n [WatchEvent.RECONNECT]: retryCount =>\n logEvent(\n WatchEvent.RECONNECT,\n `Reconnecting after ${retryCount} attempt${retryCount === 1 ? \"\" : \"s\"}`,\n ),\n [WatchEvent.RECONNECT_PENDING]: () => logEvent(WatchEvent.RECONNECT_PENDING),\n [WatchEvent.ABORT]: err => logEvent(WatchEvent.ABORT, err.message),\n [WatchEvent.OLD_RESOURCE_VERSION]: errMessage =>\n logEvent(WatchEvent.OLD_RESOURCE_VERSION, errMessage),\n [WatchEvent.NETWORK_ERROR]: err => logEvent(WatchEvent.NETWORK_ERROR, err.message),\n [WatchEvent.LIST_ERROR]: err => logEvent(WatchEvent.LIST_ERROR, err.message),\n [WatchEvent.LIST]: list => logEvent(WatchEvent.LIST, JSON.stringify(list, undefined, 2)),\n [WatchEvent.CACHE_MISS]: windowName => metricsCollector.incCacheMiss(windowName),\n [WatchEvent.INIT_CACHE_MISS]: windowName => metricsCollector.initCacheMissWindow(windowName),\n [WatchEvent.INC_RESYNC_FAILURE_COUNT]: retryCount => metricsCollector.incRetryCount(retryCount),\n };\n\n Object.entries(eventHandlers).forEach(([event, handler]) => {\n watcher.events.on(event, handler);\n });\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// SPDX-FileCopyrightText: 2023-Present The Pepr Authors\nimport { KubernetesObject } from \"@kubernetes/client-node\";\nimport { WatchPhase } from \"kubernetes-fluent-client/dist/fluent/shared-types\";\nimport { randomBytes } from \"node:crypto\";\nimport Log from \"../telemetry/logger\";\n\ntype WatchCallback = (obj: KubernetesObject, phase: WatchPhase) => Promise<void>;\n\ntype QueueItem<K extends KubernetesObject> = {\n item: K;\n phase: WatchPhase;\n callback: WatchCallback;\n resolve: (value: void | PromiseLike<void>) => void;\n reject: (reason?: string) => void;\n};\n\n/**\n * Queue is a FIFO queue for reconciling\n */\nexport class Queue<K extends KubernetesObject> {\n #name: string;\n #uid: string;\n #queue: QueueItem<K>[] = [];\n #pendingPromise = false;\n\n constructor(name: string) {\n this.#name = name;\n this.#uid = `${Date.now()}-${randomBytes(2).toString(\"hex\")}`;\n }\n\n label(): { name: string; uid: string } {\n return { name: this.#name, uid: this.#uid };\n }\n\n stats(): {\n queue: {\n name: string;\n uid: string;\n };\n stats: {\n length: number;\n };\n } {\n return {\n queue: this.label(),\n stats: {\n length: this.#queue.length,\n },\n };\n }\n\n /**\n * Enqueue adds an item to the queue and returns a promise that resolves when the item is\n * reconciled.\n *\n * @param item The object to reconcile\n * @param type The watch phase requested for reconcile\n * @param reconcile The callback to enqueue for reconcile\n * @returns A promise that resolves when the object is reconciled\n */\n enqueue(item: K, phase: WatchPhase, reconcile: WatchCallback): Promise<void> {\n const note = {\n queue: this.label(),\n item: {\n name: item.metadata?.name,\n namespace: item.metadata?.namespace,\n resourceVersion: item.metadata?.resourceVersion,\n },\n };\n Log.debug(note, \"Enqueueing\");\n return new Promise<void>((resolve, reject) => {\n this.#queue.push({ item, phase, callback: reconcile, resolve, reject });\n Log.debug(this.stats(), \"Queue stats - push\");\n return this.#dequeue();\n });\n }\n\n /**\n * Dequeue reconciles the next item in the queue\n *\n * @returns A promise that resolves when the webapp is reconciled\n */\n async #dequeue(): Promise<false | undefined> {\n // If there is a pending promise, do nothing\n if (this.#pendingPromise) {\n Log.debug(\"Pending promise, not dequeuing\");\n return false;\n }\n\n // Take the next element from the queue\n const element = this.#queue.shift();\n\n // If there is no element, do nothing\n if (!element) {\n Log.debug(\"No element, not dequeuing\");\n return false;\n }\n\n try {\n // Set the pending promise flag to avoid concurrent reconciliations\n this.#pendingPromise = true;\n\n // Reconcile the element\n const note = {\n queue: this.label(),\n item: {\n name: element.item.metadata?.name,\n namespace: element.item.metadata?.namespace,\n resourceVersion: element.item.metadata?.resourceVersion,\n },\n };\n Log.debug(note, \"Reconciling\");\n await element.callback(element.item, element.phase);\n Log.debug(note, \"Reconciled\");\n\n element.resolve();\n } catch (e) {\n Log.debug({ error: e }, `Error reconciling ${element.item.metadata!.name}`);\n element.reject(e);\n } finally {\n Log.debug(this.stats(), \"Queue stats - shift\");\n\n // Reset the pending promise flag\n Log.debug(\"Resetting pending promise and dequeuing\");\n this.#pendingPromise = false;\n\n // After the element is reconciled, dequeue the next element\n await this.#dequeue();\n }\n }\n}\n", "import { ControllerHooks } from \".\";\nimport { resolveIgnoreNamespaces } from \"../assets/ignoredNamespaces\";\nimport { Capability } from \"../core/capability\";\nimport { isWatchMode, isDevMode } from \"../core/envChecks\";\nimport { setupWatch } from \"../processors/watch-processor\";\nimport { PeprModuleOptions } from \"../types\";\n\n/**\n * Creates controller hooks with proper handling of watch setup\n *\n * @param opts Module options including hooks\n * @param capabilities List of capabilities\n * @param ignoreNamespaces Namespaces to ignore\n * @returns Controller hooks configuration\n */\nexport function createControllerHooks(\n opts: PeprModuleOptions,\n capabilities: Capability[],\n ignoreNamespaces: string[] = [],\n): ControllerHooks {\n return {\n beforeHook: opts.beforeHook,\n afterHook: opts.afterHook,\n onReady: async (): Promise<void> => {\n if (isWatchMode() || isDevMode()) {\n try {\n setupWatch(capabilities, resolveIgnoreNamespaces(ignoreNamespaces));\n } catch (error) {\n throw new Error(`WatchError: Could not set up watch.`, { cause: error });\n }\n }\n },\n };\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// SPDX-FileCopyrightText: 2023-Present The Pepr Authors\n\nimport { PeprValidateRequest } from \"../lib/validate-request\";\nimport { PeprMutateRequest } from \"../lib/mutate-request\";\nimport { V1OwnerReference, V1Container } from \"@kubernetes/client-node\";\nimport { GenericKind, K8s, kind } from \"kubernetes-fluent-client\";\n\n/**\n * Returns all containers in a pod\n * @param request the request/pod to get the containers from\n * @param containerType the type of container to get\n * @returns the list of containers in the pod\n */\nexport function containers(\n request: PeprValidateRequest<kind.Pod> | PeprMutateRequest<kind.Pod>,\n containerType?: \"containers\" | \"initContainers\" | \"ephemeralContainers\",\n): V1Container[] {\n const containers = request.Raw.spec?.containers || [];\n const initContainers = request.Raw.spec?.initContainers || [];\n const ephemeralContainers = request.Raw.spec?.ephemeralContainers || [];\n\n if (containerType === \"containers\") {\n return containers;\n }\n if (containerType === \"initContainers\") {\n return initContainers;\n }\n if (containerType === \"ephemeralContainers\") {\n return ephemeralContainers;\n }\n return [...containers, ...initContainers, ...ephemeralContainers];\n}\n\n/**\n * Write a K8s event for a CRD\n *\n * @param cr The custom resource to write the event for\n * @param event The event to write, should contain a human-readable message for the event\n * @param eventType The type of event to write, for example \"Warning\"\n * @param eventReason The reason for the event, for example \"ReconciliationFailed\"\n * @param reportingComponent The component that is reporting the event, for example \"uds.dev/operator\"\n * @param reportingInstance The instance of the component that is reporting the event, for example process.env.HOSTNAME\n */\n\nexport async function writeEvent(\n cr: GenericKind,\n event: Partial<kind.CoreEvent>,\n options: {\n eventType: string;\n eventReason: string;\n reportingComponent: string;\n reportingInstance: string;\n },\n): Promise<void> {\n const { eventType, eventReason, reportingComponent, reportingInstance } = options;\n\n await K8s(kind.CoreEvent).Create({\n type: eventType,\n reason: eventReason,\n ...event,\n // Fixed values\n metadata: {\n namespace: cr.metadata!.namespace,\n generateName: cr.metadata!.name,\n },\n involvedObject: {\n apiVersion: cr.apiVersion,\n kind: cr.kind,\n name: cr.metadata!.name,\n namespace: cr.metadata!.namespace,\n uid: cr.metadata!.uid,\n },\n firstTimestamp: new Date(),\n reportingComponent: reportingComponent,\n reportingInstance: reportingInstance,\n });\n}\n\n/**\n * Get the owner reference for a custom resource\n * @param customResource the custom resource to get the owner reference for\n * @param blockOwnerDeletion if true, AND if the owner has the \"foregroundDeletion\" finalizer, then the owner cannot be deleted from the key-value store until this reference is removed.\n * @param controller if true, this reference points to the managing controller.\n * @returns the owner reference array for the custom resource\n */\nexport function getOwnerRefFrom(\n customResource: GenericKind,\n blockOwnerDeletion?: boolean,\n controller?: boolean,\n): V1OwnerReference[] {\n const { apiVersion, kind, metadata } = customResource;\n const { name, uid } = metadata!;\n\n return [\n {\n apiVersion: apiVersion!,\n kind: kind!,\n uid: uid!,\n name: name!,\n ...(blockOwnerDeletion !== undefined && { blockOwnerDeletion }),\n ...(controller !== undefined && { controller }),\n },\n ];\n}\n\n/**\n * Sanitize a resource name to make it a valid Kubernetes resource name.\n *\n * @param name the name of the resource to sanitize\n * @returns the sanitized resource name\n *\n * https://kubernetes.io/docs/concepts/overview/working-with-objects/names/\n */\nexport function sanitizeResourceName(name: string): string {\n return (\n name\n .toLowerCase()\n // Replace invalid characters (anything not a-z, 0-9, or '-') with '-'\n .replace(/[^a-z0-9-]+/g, \"-\")\n // Trim to 63 characters (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#rfc-1035-label-names)\n .slice(0, 63)\n // Remove leading non-alphanumeric characters\n .replace(/^[^a-z0-9]+/, \"\")\n // Remove trailing non-alphanumeric characters\n .replace(/[^a-z0-9]+$/, \"\")\n );\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["import { K8s, RegisterKind, kind as a, fetch, fetchStatus, kind } from \"kubernetes-fluent-client\";\nimport * as R from \"ramda\";\n\nimport { Capability } from \"./lib/core/capability\";\nimport Log from \"./lib/telemetry/logger\";\nimport { PeprModule } from \"./lib/core/module\";\nimport { PeprMutateRequest } from \"./lib/mutate-request\";\nimport * as PeprUtils from \"./lib/utils\";\nimport { PeprValidateRequest } from \"./lib/validate-request\";\nimport * as sdk from \"./sdk/sdk\";\nimport { metricsCollector } from \"./lib/telemetry/metrics\";\n\nexport {\n metricsCollector,\n Capability,\n K8s,\n Log,\n PeprModule,\n PeprMutateRequest,\n PeprUtils,\n PeprValidateRequest,\n R,\n RegisterKind,\n a,\n fetch,\n fetchStatus,\n kind,\n sdk,\n};\n", "// SPDX-License-Identifier: Apache-2.0\n// SPDX-FileCopyrightText: 2023-Present The Pepr Authors\n\nimport { GenericClass, GroupVersionKind, modelToGroupVersionKind } from \"kubernetes-fluent-client\";\nimport { pickBy } from \"ramda\";\nimport Log from \"../telemetry/logger\";\nimport { isBuildMode, isDevMode, isWatchMode } from \"./envChecks\";\nimport { PeprStore, Storage } from \"./storage\";\nimport { OnSchedule, Schedule } from \"./schedule\";\nimport { Event } from \"../enums\";\nimport {\n Binding,\n BindingFilter,\n BindingWithName,\n CapabilityCfg,\n CapabilityExport,\n MutateAction,\n MutateActionChain,\n ValidateAction,\n ValidateActionChain,\n WatchLogAction,\n FinalizeAction,\n FinalizeActionChain,\n WhenSelector,\n} from \"../types\";\nimport { addFinalizer } from \"../finalizer\";\n\nconst registerAdmission = isBuildMode() || !isWatchMode();\nconst registerWatch = isBuildMode() || isWatchMode() || isDevMode();\n\n/**\n * A capability is a unit of functionality that can be registered with the Pepr runtime.\n */\nexport class Capability implements CapabilityExport {\n #name: string;\n #description: string;\n #namespaces?: string[] | undefined;\n #bindings: Binding[] = [];\n #store = new Storage();\n #scheduleStore = new Storage();\n #registered = false;\n #scheduleRegistered = false;\n hasSchedule: boolean;\n\n /**\n * Run code on a schedule with the capability.\n *\n * @param schedule The schedule to run the code on\n * @returns\n */\n OnSchedule: (schedule: Schedule) => void = (schedule: Schedule) => {\n const { name, every, unit, run, startTime, completions } = schedule;\n this.hasSchedule = true;\n\n if (process.env.PEPR_WATCH_MODE === \"true\" || process.env.PEPR_MODE === \"dev\") {\n // Only create/watch schedule store if necessary\n\n // Create a new schedule\n const newSchedule: Schedule = {\n name,\n every,\n unit,\n run,\n startTime,\n completions,\n };\n\n this.#scheduleStore.onReady(() => {\n new OnSchedule(newSchedule).setStore(this.#scheduleStore);\n });\n }\n };\n\n public getScheduleStore(): Storage {\n return this.#scheduleStore;\n }\n\n /**\n * Store is a key-value data store that can be used to persist data that should be shared\n * between requests. Each capability has its own store, and the data is persisted in Kubernetes\n * in the `pepr-system` namespace.\n *\n * Note: You should only access the store from within an action.\n */\n Store: PeprStore = {\n clear: this.#store.clear,\n getItem: this.#store.getItem,\n removeItem: this.#store.removeItem,\n removeItemAndWait: this.#store.removeItemAndWait,\n setItem: this.#store.setItem,\n subscribe: this.#store.subscribe,\n onReady: this.#store.onReady,\n setItemAndWait: this.#store.setItemAndWait,\n };\n\n /**\n * ScheduleStore is a key-value data store used to persist schedule data that should be shared\n * between intervals. Each Schedule shares store, and the data is persisted in Kubernetes\n * in the `pepr-system` namespace.\n *\n * Note: There is no direct access to schedule store\n */\n ScheduleStore: PeprStore = {\n clear: this.#scheduleStore.clear,\n getItem: this.#scheduleStore.getItem,\n removeItemAndWait: this.#scheduleStore.removeItemAndWait,\n removeItem: this.#scheduleStore.removeItem,\n setItemAndWait: this.#scheduleStore.setItemAndWait,\n setItem: this.#scheduleStore.setItem,\n subscribe: this.#scheduleStore.subscribe,\n onReady: this.#scheduleStore.onReady,\n };\n\n get bindings(): Binding[] {\n return this.#bindings;\n }\n\n get name(): string {\n return this.#name;\n }\n\n get description(): string {\n return this.#description;\n }\n\n get namespaces(): string[] {\n return this.#namespaces || [];\n }\n\n constructor(cfg: CapabilityCfg) {\n this.#name = cfg.name;\n this.#description = cfg.description;\n this.#namespaces = cfg.namespaces;\n this.hasSchedule = false;\n\n Log.debug(`Capability ${this.#name} registered`);\n Log.debug(cfg);\n }\n\n /**\n * Register the store with the capability. This is called automatically by the Pepr controller.\n */\n registerScheduleStore = (): Storage => {\n Log.debug(`Registering schedule store for ${this.#name}`);\n\n if (this.#scheduleRegistered) {\n throw new Error(`Schedule store already registered for ${this.#name}`);\n }\n\n this.#scheduleRegistered = true;\n\n // Pass back any ready callback to the controller\n return this.#scheduleStore;\n };\n\n /**\n * Register the store with the capability. This is called automatically by the Pepr controller.\n *\n * @param store\n */\n registerStore = (): Storage => {\n Log.debug(`Registering store for ${this.#name}`);\n\n if (this.#registered) {\n throw new Error(`Store already registered for ${this.#name}`);\n }\n\n this.#registered = true;\n\n // Pass back any ready callback to the controller\n return this.#store;\n };\n\n /**\n * The When method is used to register a action to be executed when a Kubernetes resource is\n * processed by Pepr. The action will be executed if the resource matches the specified kind and any\n * filters that are applied.\n *\n * @param model the KubernetesObject model to match\n * @param kind if using a custom KubernetesObject not available in `a.*`, specify the GroupVersionKind\n * @returns\n */\n // This method intentionally defines a fluent, closure-based DSL for chaining capability actions.\n // Multiple inline helper functions are required to preserve runtime behavior and readability.\n // eslint-disable-next-line max-statements\n When = <T extends GenericClass>(model: T, kind?: GroupVersionKind): WhenSelector<T> => {\n const matchedKind = modelToGroupVersionKind(model.name);\n\n // If the kind is not specified and the model is not a KubernetesObject, throw an error\n if (!matchedKind && !kind) {\n throw new Error(`Kind not specified for ${model.name}`);\n }\n\n const binding: Binding = {\n model,\n // If the kind is not specified, use the matched kind from the model\n kind: kind || matchedKind,\n event: Event.ANY,\n filters: {\n name: \"\",\n namespaces: [],\n regexNamespaces: [],\n regexName: \"\",\n labels: {},\n annotations: {},\n deletionTimestamp: false,\n },\n };\n\n const bindings = this.#bindings;\n const prefix = `${this.#name}: ${model.name}`;\n const commonChain = {\n WithLabel,\n WithAnnotation,\n WithDeletionTimestamp,\n Mutate,\n Validate,\n Watch,\n Reconcile,\n Alias,\n };\n\n type CommonChainType = typeof commonChain;\n type ExtendedCommonChainType = CommonChainType & {\n Alias: (alias: string) => CommonChainType;\n InNamespace: (...namespaces: string[]) => BindingWithName<T>;\n InNamespaceRegex: (...namespaces: RegExp[]) => BindingWithName<T>;\n WithName: (name: string) => BindingFilter<T>;\n WithNameRegex: (regexName: RegExp) => BindingFilter<T>;\n WithDeletionTimestamp: () => BindingFilter<T>;\n };\n\n const isNotEmpty = (value: object): boolean => Object.keys(value).length > 0;\n const log = (message: string, cbString: string): void => {\n const filteredObj = pickBy(isNotEmpty, binding.filters);\n\n Log.info({ prefix }, `${message} configured for ${binding.event}`);\n Log.info({ prefix }, JSON.stringify(filteredObj));\n Log.debug({ prefix }, cbString);\n };\n\n function Validate(validateCallback: ValidateAction<T>): ValidateActionChain<T> {\n if (registerAdmission) {\n log(\"Validate Action\", validateCallback.toString());\n\n // Create the child logger\n const aliasLogger = Log.child({ alias: binding.alias || \"no alias provided\" });\n\n // Push the binding to the list of bindings for this capability as a new BindingAction\n // with the callback function to preserve\n bindings.push({\n ...binding,\n isValidate: true,\n validateCallback: async (req, logger = aliasLogger) => {\n if (binding.alias) {\n Log.info(`Executing validate action with alias: ${binding.alias}`);\n }\n return await validateCallback(req, logger);\n },\n });\n }\n\n return { Watch, Reconcile };\n }\n\n function Mutate(mutateCallback: MutateAction<T>): MutateActionChain<T> {\n if (registerAdmission) {\n log(\"Mutate Action\", mutateCallback.toString());\n\n // Create the child logger\n const aliasLogger = Log.child({ alias: binding.alias || \"no alias provided\" });\n\n // Push the binding to the list of bindings for this capability as a new BindingAction\n // with the callback function to preserve\n bindings.push({\n ...binding,\n isMutate: true,\n mutateCallback: async (req, logger = aliasLogger) => {\n if (binding.alias) {\n Log.info(`Executing mutation action with alias: ${binding.alias}`);\n }\n await mutateCallback(req, logger);\n },\n });\n }\n\n // Now only allow adding actions to the same binding\n return { Watch, Validate, Reconcile };\n }\n\n function Watch(watchCallback: WatchLogAction<T>): FinalizeActionChain<T> {\n if (registerWatch) {\n log(\"Watch Action\", watchCallback.toString());\n\n // Create the child logger and cast it to the expected type\n const aliasLogger = Log.child({\n alias: binding.alias || \"no alias provided\",\n }) as typeof Log;\n\n // Push the binding to the list of bindings for this capability as a new BindingAction\n // with the callback function to preserve\n bindings.push({\n ...binding,\n isWatch: true,\n watchCallback: async (update, phase, logger = aliasLogger) => {\n if (binding.alias) {\n Log.info(`Executing watch action with alias: ${binding.alias}`);\n }\n await watchCallback(update, phase, logger);\n },\n });\n }\n return { Finalize };\n }\n\n function Reconcile(reconcileCallback: WatchLogAction<T>): FinalizeActionChain<T> {\n if (registerWatch) {\n log(\"Reconcile Action\", reconcileCallback.toString());\n\n // Create the child logger and cast it to the expected type\n const aliasLogger = Log.child({\n alias: binding.alias || \"no alias provided\",\n }) as typeof Log;\n\n // Push the binding to the list of bindings for this capability as a new BindingAction\n // with the callback function to preserve\n bindings.push({\n ...binding,\n isWatch: true,\n isQueue: true,\n watchCallback: async (update, phase, logger = aliasLogger) => {\n if (binding.alias) {\n Log.info(`Executing reconcile action with alias: ${binding.alias}`);\n }\n await reconcileCallback(update, phase, logger);\n },\n });\n }\n return { Finalize };\n }\n\n function Finalize(finalizeCallback: FinalizeAction<T>): void {\n log(\"Finalize Action\", finalizeCallback.toString());\n\n // Create the child logger and cast it to the expected type\n const aliasLogger = Log.child({ alias: binding.alias || \"no alias provided\" }) as typeof Log;\n\n // Add binding to inject Pepr finalizer during admission (Mutate)\n if (registerAdmission) {\n const mutateBinding = {\n ...binding,\n isMutate: true,\n isFinalize: true,\n event: Event.ANY,\n mutateCallback: addFinalizer,\n };\n bindings.push(mutateBinding);\n }\n\n // Add binding to process finalizer callback / remove Pepr finalizer (Watch)\n if (registerWatch) {\n const watchBinding = {\n ...binding,\n isWatch: true,\n isFinalize: true,\n event: Event.UPDATE,\n finalizeCallback: async (\n update: InstanceType<T>,\n logger = aliasLogger,\n ): Promise<boolean | void> => {\n if (binding.alias) {\n Log.info(`Executing finalize action with alias: ${binding.alias}`);\n }\n return await finalizeCallback(update, logger);\n },\n };\n bindings.push(watchBinding);\n }\n }\n\n function InNamespace(...namespaces: string[]): BindingWithName<T> {\n Log.debug({ prefix }, `Add namespaces filter ${namespaces}`);\n binding.filters.namespaces.push(...namespaces);\n return { ...commonChain, WithName, WithNameRegex };\n }\n\n function InNamespaceRegex(...namespaces: RegExp[]): BindingWithName<T> {\n Log.debug({ prefix }, `Add regex namespaces filter ${namespaces}`);\n binding.filters.regexNamespaces.push(...namespaces.map(regex => regex.source));\n return { ...commonChain, WithName, WithNameRegex };\n }\n\n function WithDeletionTimestamp(): BindingFilter<T> {\n Log.debug({ prefix }, \"Add deletionTimestamp filter\");\n binding.filters.deletionTimestamp = true;\n return commonChain;\n }\n\n function WithNameRegex(regexName: RegExp): BindingFilter<T> {\n Log.debug({ prefix }, `Add regex name filter ${regexName}`);\n binding.filters.regexName = regexName.source;\n return commonChain;\n }\n\n function WithName(name: string): BindingFilter<T> {\n Log.debug({ prefix }, `Add name filter ${name}`);\n binding.filters.name = name;\n return commonChain;\n }\n\n function WithLabel(key: string, value = \"\"): BindingFilter<T> {\n Log.debug({ prefix }, `Add label filter ${key}=${value}`);\n binding.filters.labels[key] = value;\n return commonChain;\n }\n\n function WithAnnotation(key: string, value = \"\"): BindingFilter<T> {\n Log.debug({ prefix }, `Add annotation filter ${key}=${value}`);\n binding.filters.annotations[key] = value;\n return commonChain;\n }\n\n function Alias(alias: string): CommonChainType {\n Log.debug({ prefix }, `Adding prefix alias ${alias}`);\n binding.alias = alias;\n return commonChain;\n }\n\n function bindEvent(event: Event): ExtendedCommonChainType {\n binding.event = event;\n return {\n ...commonChain,\n InNamespace,\n InNamespaceRegex,\n WithName,\n WithNameRegex,\n WithDeletionTimestamp,\n Alias,\n };\n }\n\n return {\n IsCreatedOrUpdated: () => bindEvent(Event.CREATE_OR_UPDATE),\n IsCreated: () => bindEvent(Event.CREATE),\n IsUpdated: () => bindEvent(Event.UPDATE),\n IsDeleted: () => bindEvent(Event.DELETE),\n };\n };\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// SPDX-FileCopyrightText: 2023-Present The Pepr Authors\n\nimport { Operation } from \"fast-json-patch\";\nimport { pino, stdTimeFunctions } from \"pino\";\nimport { Store } from \"../k8s\";\n\nconst isPrettyLog = process.env.PEPR_PRETTY_LOGS === \"true\";\nconst redactedValue = \"**redacted**\";\n\nconst pretty = {\n target: \"pino-pretty\",\n options: {\n colorize: true,\n },\n};\n\nconst transport = isPrettyLog ? pretty : undefined;\n// epochTime is the pino default\nconst pinoTimeFunction =\n process.env.PINO_TIME_STAMP === \"iso\"\n ? (): string => stdTimeFunctions.isoTime()\n : (): string => stdTimeFunctions.epochTime();\nconst Log = pino({\n transport,\n timestamp: pinoTimeFunction,\n});\n\nif (process.env.LOG_LEVEL) {\n Log.level = process.env.LOG_LEVEL;\n}\n\nexport function redactedStore(store: Store): Store {\n const redacted = process.env.PEPR_STORE_REDACT_VALUES === \"true\";\n return {\n ...store,\n data: Object.keys(store.data).reduce((acc: Record<string, string>, key: string) => {\n acc[key] = redacted ? redactedValue : store.data[key];\n return acc;\n }, {}),\n };\n}\n\nexport function redactedPatch(patch: Record<string, Operation> = {}): Record<string, Operation> {\n const redacted = process.env.PEPR_STORE_REDACT_VALUES === \"true\";\n\n if (!redacted) {\n return patch;\n }\n\n const redactedCache: Record<string, Operation> = {};\n\n Object.entries(patch).forEach(([key, operation]) => {\n const isRedacted = key.includes(\":\");\n const targetKey = isRedacted ? `${key.substring(0, key.lastIndexOf(\":\"))}:**redacted**` : key;\n\n const redactedOperation = isRedacted\n ? {\n ...operation,\n ...(Object.hasOwn(operation, \"value\") ? { value: redactedValue } : {}),\n }\n : operation;\n\n redactedCache[targetKey] = redactedOperation;\n });\n\n return redactedCache;\n}\n\nexport default Log;\n", "export const isWatchMode = (): boolean => process.env.PEPR_WATCH_MODE === \"true\";\n// Track if Pepr is running in build mode\n\nexport const isBuildMode = (): boolean => process.env.PEPR_MODE === \"build\";\n\nexport const isDevMode = (): boolean => process.env.PEPR_MODE === \"dev\";\n", "// SPDX-License-Identifier: Apache-2.0\n// SPDX-FileCopyrightText: 2023-Present The Pepr Authors\n\nimport { clone } from \"ramda\";\nimport pointer from \"json-pointer\";\nexport type DataOp = \"add\" | \"remove\";\nexport type DataStore = Record<string, string>;\nexport type DataSender = (op: DataOp, keys: string[], value?: string) => void;\ntype DataReceiver = (data: DataStore) => void;\nexport type Unsubscribe = () => void;\n\nconst MAX_WAIT_TIME = 15000;\nconst STORE_VERSION_PREFIX = \"v2\";\n\ninterface WaitRecord {\n timeout?: ReturnType<typeof setTimeout>;\n unsubscribe?: () => void;\n}\n\nexport function v2StoreKey(key: string): string {\n return `${STORE_VERSION_PREFIX}-${pointer.escape(key)}`;\n}\n\nexport function v2UnescapedStoreKey(key: string): string {\n return `${STORE_VERSION_PREFIX}-${key}`;\n}\n\nexport function stripV2Prefix(key: string): string {\n return key.replace(/^v2-/, \"\");\n}\nexport interface PeprStore {\n /**\n * Returns the current value associated with the given key, or null if the given key does not exist.\n */\n getItem(key: string): string | null;\n /**\n * Removes all key/value pairs, if there are any.\n */\n clear(): void;\n /**\n * Removes the key/value pair with the given key, if a key/value pair with the given key exists.\n */\n removeItem(key: string): void;\n /**\n * Sets the value of the pair identified by key to value, creating a new key/value pair if none existed for key previously.\n */\n setItem(key: string, value: string): void;\n\n /**\n * Subscribe to changes in the store. This API behaves similarly to the [Svelte Store API](https://vercel.com/docs/beginner-sveltekit/svelte-stores#using-the-store).\n *\n * @param listener - The callback to be invoked when the store changes.\n * @returns A function to unsubscribe from the listener.\n */\n subscribe(listener: DataReceiver): Unsubscribe;\n\n /**\n * Register a function to be called when the store is ready.\n */\n onReady(callback: DataReceiver): void;\n\n /**\n * Sets the value of the pair identified by key to value, creating a new key/value pair if none existed for key previously.\n * Resolves when the key/value show up in the store.\n */\n setItemAndWait(key: string, value: string): Promise<string>;\n\n /**\n * Remove the value of the key.\n * Resolves when the key does not show up in the store.\n */\n removeItemAndWait(key: string): Promise<string>;\n}\n\n/**\n * A key-value data store that can be used to persist data that should be shared across Pepr controllers and capabilities.\n *\n * The API is similar to the [Storage API](https://developer.mozilla.org/docs/Web/API/Storage)\n */\n\nexport class Storage implements PeprStore {\n #store: DataStore = {};\n #send!: DataSender;\n #subscribers: Record<number, DataReceiver> = {};\n #subscriberId = 0;\n #readyHandlers: DataReceiver[] = [];\n\n registerSender = (send: DataSender): void => {\n this.#send = send;\n };\n\n receive = (data: DataStore): void => {\n this.#store = data || {};\n\n this.#onReady();\n\n // Notify all subscribers\n for (const idx in this.#subscribers) {\n // Send a unique clone of the store to each subscriber\n this.#subscribers[idx](clone(this.#store));\n }\n };\n\n getItem = (key: string): string | null => {\n const result = this.#store[v2UnescapedStoreKey(key)] || null;\n if (result !== null && typeof result !== \"function\" && typeof result !== \"object\") {\n return result;\n }\n return null;\n };\n\n clear = (): void => {\n if (Object.keys(this.#store).length > 0) {\n this.#dispatchUpdate(\n \"remove\",\n Object.keys(this.#store).map(key => pointer.escape(key)),\n );\n }\n };\n\n removeItem = (key: string): void => {\n this.#dispatchUpdate(\"remove\", [v2StoreKey(key)]);\n };\n\n setItem = (key: string, value: string): void => {\n this.#dispatchUpdate(\"add\", [v2StoreKey(key)], value);\n };\n\n /**\n * Creates a promise and subscribes to the store, the promise resolves when\n * the key and value are seen in the store.\n *\n * @param key - The key to add into the store\n * @param value - The value of the key\n * @returns\n */\n setItemAndWait = (key: string, value: string): Promise<string> => {\n this.#dispatchUpdate(\"add\", [v2StoreKey(key)], value);\n const record: WaitRecord = {};\n\n return new Promise<string>((resolve, reject) => {\n // If promise has not resolved before MAX_WAIT_TIME reject\n record.timeout = setTimeout(() => {\n record.unsubscribe!();\n return reject(`MAX_WAIT_TIME elapsed: Key ${key} not seen in ${MAX_WAIT_TIME / 1000}s`);\n }, MAX_WAIT_TIME);\n\n record.unsubscribe = this.subscribe(data => {\n if (data[`${v2UnescapedStoreKey(key)}`] === value) {\n record.unsubscribe!();\n clearTimeout(record.timeout);\n resolve(\"ok\");\n }\n });\n });\n };\n\n /**\n * Creates a promise and subscribes to the store, the promise resolves when\n * the key is removed from the store.\n *\n * @param key - The key to add into the store\n * @returns\n */\n removeItemAndWait = (key: string): Promise<string> => {\n this.#dispatchUpdate(\"remove\", [v2StoreKey(key)]);\n const record: WaitRecord = {};\n return new Promise<string>((resolve, reject) => {\n // If promise has not resolved before MAX_WAIT_TIME reject\n record.timeout = setTimeout(() => {\n record.unsubscribe!();\n return reject(\n `MAX_WAIT_TIME elapsed: Key ${key} still seen after ${MAX_WAIT_TIME / 1000}s`,\n );\n }, MAX_WAIT_TIME);\n\n record.unsubscribe = this.subscribe(data => {\n if (!Object.hasOwn(data, `${v2UnescapedStoreKey(key)}`)) {\n record.unsubscribe!();\n clearTimeout(record.timeout);\n resolve(\"ok\");\n }\n });\n });\n };\n\n subscribe = (subscriber: DataReceiver): (() => void) => {\n const idx = this.#subscriberId++;\n this.#subscribers[idx] = subscriber;\n return () => this.unsubscribe(idx);\n };\n\n onReady = (callback: DataReceiver): void => {\n this.#readyHandlers.push(callback);\n };\n\n /**\n * Remove a subscriber from the list of subscribers.\n * @param idx - The index of the subscriber to remove.\n */\n unsubscribe = (idx: number): void => {\n delete this.#subscribers[idx];\n };\n\n #onReady = (): void => {\n // Notify all ready handlers with a clone of the store\n for (const handler of this.#readyHandlers) {\n handler(clone(this.#store));\n }\n\n // Make this a noop so that it can't be called again\n this.#onReady = (): void => {};\n };\n\n /**\n * Dispatch an update to the store and notify all subscribers.\n * @param op - The type of operation to perform.\n * @param keys - The keys to update.\n * @param [value] - The new value.\n */\n #dispatchUpdate = (op: DataOp, keys: string[], value?: string): void => {\n this.#send(op, keys, value);\n };\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// SPDX-FileCopyrightText: 2023-Present The Pepr Authors\n\nimport { PeprStore } from \"./storage\";\n\nexport type Unit = \"seconds\" | \"second\" | \"minute\" | \"minutes\" | \"hours\" | \"hour\";\n\nexport interface Schedule {\n /**\n * * The name of the store\n */\n name: string;\n /**\n * The value associated with a unit of time\n */\n every: number;\n /**\n * The unit of time\n */\n unit: Unit;\n /**\n * The code to run\n */\n run: () => void;\n /**\n * The start time of the schedule\n */\n startTime?: Date | undefined;\n\n /**\n * The number of times the schedule has run\n */\n completions?: number | undefined;\n /**\n * Tje intervalID to clear the interval\n */\n intervalID?: NodeJS.Timeout;\n}\n\nexport class OnSchedule implements Schedule {\n intervalId: NodeJS.Timeout | null = null;\n store: PeprStore | undefined;\n name!: string;\n completions?: number | undefined;\n every: number;\n unit: Unit;\n run!: () => void;\n startTime?: Date | undefined;\n duration: number | undefined;\n lastTimestamp: Date | undefined;\n\n constructor(schedule: Schedule) {\n this.name = schedule.name;\n this.run = schedule.run;\n this.every = schedule.every;\n this.unit = schedule.unit;\n this.startTime = schedule?.startTime;\n this.completions = schedule?.completions;\n }\n setStore(store: PeprStore): void {\n this.store = store;\n this.startInterval();\n }\n startInterval(): void {\n this.checkStore();\n this.getDuration();\n this.setupInterval();\n }\n /**\n * Checks the store for this schedule and sets the values if it exists\n * @returns\n */\n checkStore(): void {\n const result = this.store && this.store.getItem(this.name);\n if (result) {\n const storedSchedule = JSON.parse(result);\n this.completions = storedSchedule?.completions;\n this.startTime = storedSchedule?.startTime;\n this.lastTimestamp = storedSchedule?.lastTimestamp;\n }\n }\n\n /**\n * Saves the schedule to the store\n * @returns\n */\n saveToStore(): void {\n const schedule = {\n completions: this.completions,\n startTime: this.startTime,\n lastTimestamp: new Date(),\n name: this.name,\n };\n if (this.store) this.store.setItem(this.name, JSON.stringify(schedule));\n }\n\n /**\n * Gets the durations in milliseconds\n */\n getDuration(): void {\n switch (this.unit) {\n case \"seconds\":\n if (this.every < 10) throw new Error(\"10 Seconds in the smallest interval allowed\");\n this.duration = 1000 * this.every;\n break;\n case \"minutes\":\n case \"minute\":\n this.duration = 1000 * 60 * this.every;\n break;\n case \"hours\":\n case \"hour\":\n this.duration = 1000 * 60 * 60 * this.every;\n break;\n default:\n throw new Error(\"Invalid time unit\");\n }\n }\n\n /**\n * Sets up the interval\n */\n setupInterval(): void {\n const now = new Date();\n let delay: number | undefined;\n\n if (this.lastTimestamp && this.startTime) {\n this.startTime = undefined;\n }\n\n if (this.startTime) {\n delay = this.startTime.getTime() - now.getTime();\n } else if (this.lastTimestamp && this.duration) {\n const lastTimestamp = new Date(this.lastTimestamp);\n delay = this.duration - (now.getTime() - lastTimestamp.getTime());\n }\n\n if (delay === undefined || delay <= 0) {\n this.start();\n } else {\n setTimeout(() => {\n this.start();\n }, delay);\n }\n }\n\n /**\n * Starts the interval\n */\n start(): void {\n this.intervalId = setInterval(() => {\n if (this.completions === 0) {\n this.stop();\n return;\n } else {\n this.run();\n\n if (this.completions && this.completions !== 0) {\n this.completions -= 1;\n }\n this.saveToStore();\n }\n }, this.duration);\n }\n\n /**\n * Stops the interval\n */\n stop(): void {\n if (this.intervalId) {\n clearInterval(this.intervalId);\n this.intervalId = null;\n }\n if (this.store) this.store.removeItem(this.name);\n }\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// SPDX-FileCopyrightText: 2023-Present The Pepr Authors\n\nimport { K8s, KubernetesObject, RegisterKind } from \"kubernetes-fluent-client\";\nimport Log from \"./telemetry/logger\";\nimport { Binding } from \"./types\";\nimport { Operation } from \"./enums\";\nimport { PeprMutateRequest } from \"./mutate-request\";\nimport { DeepPartial } from \"./common-types\";\n\nexport function addFinalizer<K extends KubernetesObject>(request: PeprMutateRequest<K>): void {\n // if a DELETE is being processed, don't add a finalizer\n if (request.Request.operation === Operation.DELETE) {\n return;\n }\n\n // if an UPDATE is being processed and it HAS a deletionTimestamp, the\n // resource is going through a pre-delete flow so don't (re-)add a finalizer\n if (request.Request.operation === Operation.UPDATE && request.Raw.metadata?.deletionTimestamp) {\n return;\n }\n\n const peprFinal = \"pepr.dev/finalizer\";\n const finalizers = request.Raw.metadata?.finalizers || [];\n if (!finalizers.includes(peprFinal)) {\n finalizers.push(peprFinal);\n }\n\n request.Merge({ metadata: { finalizers } } as DeepPartial<K>);\n}\n\nexport async function removeFinalizer(binding: Binding, obj: KubernetesObject): Promise<void> {\n const peprFinal = \"pepr.dev/finalizer\";\n const meta = obj.metadata!;\n const resource = `${meta.namespace || \"ClusterScoped\"}/${meta.name}`;\n\n Log.debug({ obj }, `Removing finalizer '${peprFinal}' from '${resource}'`);\n\n // ensure request model is registerd with KFC (for non-built in CRD's, etc.)\n const { model, kind } = binding;\n try {\n RegisterKind(model, kind);\n } catch (e) {\n const expected = e.message === `GVK ${model.name} already registered`;\n if (!expected) {\n Log.error({ model, kind, error: e }, `Error registering \"${kind}\" during finalization.`);\n return;\n }\n }\n\n // remove pepr finalizers\n const finalizers = meta.finalizers?.filter(f => f !== peprFinal) || [];\n\n // JSON Patch - replace a key\n // https://datatracker.ietf.org/doc/html/rfc6902/#section-4.3\n obj = await K8s(model, meta).Patch([\n {\n op: \"replace\",\n path: `/metadata/finalizers`,\n value: finalizers,\n },\n ]);\n Log.debug({ obj }, `Removed finalizer '${peprFinal}' from '${resource}'`);\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// SPDX-FileCopyrightText: 2023-Present The Pepr Authors\nimport { clone } from \"ramda\";\nimport { Capability } from \"./capability\";\nimport { Controller } from \"../controller\";\nimport { ValidateError } from \"../errors\";\nimport { CapabilityExport, PackageJSON, PeprModuleOptions, ModuleConfig } from \"../types\";\nimport { isBuildMode } from \"./envChecks\";\nimport { createControllerHooks } from \"../controller/createHooks\";\n\nexport class PeprModule {\n #controller!: Controller;\n\n /**\n * Initialize a new Pepr runtime module.\n *\n * @param pkg The package.json data containing Pepr configuration.\n * @param capabilities The list of capabilities to load.\n * @param opts Options for the Pepr runtime settings (e.g., deferStart).\n */\n\n constructor(\n { description, pepr }: PackageJSON,\n capabilities: Capability[] = [],\n opts: PeprModuleOptions = {},\n ) {\n const config = PeprModule.#initializeConfig(description, pepr);\n PeprModule.#validateConfig(config);\n\n if (isBuildMode()) {\n PeprModule.#handleBuildMode(capabilities);\n return;\n }\n\n const controllerHooks = PeprModule.#createHooks(opts, capabilities, pepr, config);\n this.#controller = new Controller(config, capabilities, controllerHooks);\n\n if (!opts.deferStart) {\n this.start();\n }\n }\n\n static #initializeConfig(description: string, pepr: PackageJSON[\"pepr\"]): ModuleConfig {\n const config: ModuleConfig = clone(pepr);\n config.description = description;\n return config;\n }\n\n static #validateConfig(config: ModuleConfig): void {\n ValidateError(config.onError);\n }\n\n static #handleBuildMode(capabilities: Capability[]): void {\n if (!process.send) {\n throw new Error(\"process.send is not defined\");\n }\n\n const exportedCapabilities: CapabilityExport[] = capabilities.map(cap => ({\n name: cap.name,\n description: cap.description,\n namespaces: cap.namespaces,\n bindings: cap.bindings,\n hasSchedule: cap.hasSchedule,\n }));\n\n process.send(exportedCapabilities);\n }\n\n static #createHooks(\n opts: PeprModuleOptions,\n capabilities: Capability[],\n pepr: PackageJSON[\"pepr\"],\n config: ModuleConfig,\n ): ReturnType<typeof createControllerHooks> {\n const ignored = pepr?.alwaysIgnore?.namespaces?.length\n ? pepr.alwaysIgnore.namespaces\n : config?.watch?.alwaysIgnore?.namespaces;\n\n return createControllerHooks(opts, capabilities, ignored);\n }\n /**\n * Starts the Pepr runtime manually.\n *\n * Normally this is called automatically when the Pepr module is instantiated,\n * but it can be invoked manually if `deferStart` is set to `true` in the constructor.\n *\n * @param port - The port number to start the server on (default: 3000).\n */\n start = (port = 3000): void => {\n this.#controller.startServer(port);\n };\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// SPDX-FileCopyrightText: 2023-Present The Pepr Authors\n\nimport express, { NextFunction } from \"express\";\nimport fs from \"fs\";\nimport https from \"https\";\n\nimport { Capability } from \"../core/capability\";\nimport { MutateResponse, ValidateResponse } from \"../k8s\";\nimport Log from \"../telemetry/logger\";\nimport { metricsCollector, MetricsCollector } from \"../telemetry/metrics\";\nimport { isWatchMode } from \"../core/envChecks\";\nimport { ModuleConfig } from \"../types\";\nimport { mutateProcessor } from \"../processors/mutate-processor\";\nimport { validateProcessor } from \"../processors/validate-processor\";\nimport { StoreController } from \"./store\";\nimport { karForMutate, karForValidate, KubeAdmissionReview } from \"./index.util\";\nimport { AdmissionRequest } from \"../common-types\";\nimport { featureFlagStore } from \"../features/store\";\nimport { GroupVersionKind } from \"kubernetes-fluent-client\";\n\nexport interface ControllerHooks {\n beforeHook?: (req: AdmissionRequest) => void;\n afterHook?: (res: MutateResponse | ValidateResponse) => void;\n onReady?: () => void;\n}\n\nif (!process.env.PEPR_NODE_WARNINGS) {\n process.removeAllListeners(\"warning\");\n}\n\nexport class Controller {\n // Track whether the server is running\n #running = false;\n\n // Metrics collector\n #metricsCollector = metricsCollector;\n\n // The path used to authenticate requests\n #path = \"\";\n\n // The express app instance\n readonly #app = express();\n\n // Initialized with the constructor\n readonly #config: ModuleConfig;\n readonly #capabilities: Capability[];\n readonly #beforeHook?: (req: AdmissionRequest) => void;\n readonly #afterHook?: (res: MutateResponse | ValidateResponse) => void;\n\n constructor(config: ModuleConfig, capabilities: Capability[], hooks: ControllerHooks = {}) {\n const { beforeHook, afterHook, onReady } = hooks;\n this.#config = config;\n this.#capabilities = capabilities;\n Log.info({ config }, \"Controller configuration\");\n\n // Initialize the Pepr store for each capability\n new StoreController(capabilities, `pepr-${config.uuid}-store`, () => {\n this.#bindEndpoints();\n if (typeof onReady === \"function\") {\n onReady();\n }\n Log.debug(\"Controller startup complete\");\n // Initialize the schedule store for each capability\n new StoreController(capabilities, `pepr-${config.uuid}-schedule`, () => {\n Log.debug(\"Scheduling processed\");\n });\n });\n\n // Middleware for logging requests\n this.#app.use(Controller.#logger);\n\n // Middleware for parsing JSON, limit to 2mb vs 100K for K8s compatibility\n this.#app.use(express.json({ limit: \"2mb\" }));\n\n if (beforeHook) {\n Log.info(`Using beforeHook: ${beforeHook}`);\n this.#beforeHook = beforeHook;\n }\n\n if (afterHook) {\n Log.info(`Using afterHook: ${afterHook}`);\n this.#afterHook = afterHook;\n }\n }\n\n /** Start the webhook server */\n startServer = (port: number): void => {\n if (this.#running) {\n throw new Error(\n \"Cannot start Pepr module: Pepr module was not instantiated with deferStart=true\",\n );\n }\n\n // Initialize feature store\n try {\n featureFlagStore.initialize();\n Log.info(`Feature flag store initialized: ${JSON.stringify(featureFlagStore.getAll())}`);\n } catch (error) {\n Log.warn(error, \"Could not initialize feature flags\");\n }\n // Load SSL certificate and key\n const options = {\n key: fs.readFileSync(process.env.SSL_KEY_PATH || \"/etc/certs/tls.key\"),\n cert: fs.readFileSync(process.env.SSL_CERT_PATH || \"/etc/certs/tls.crt\"),\n };\n\n // Get the API path if not in watch mode\n if (!isWatchMode()) {\n // Get the API path from the environment variable or the mounted secret\n this.#path =\n process.env.PEPR_API_PATH || fs.readFileSync(\"/app/api-path/value\").toString().trim();\n Log.info(`Using API path: ${this.#path}`);\n\n if (!this.#path) {\n throw new Error(\"API path not found\");\n }\n }\n\n // Create HTTPS server\n const server = https.createServer(options, this.#app).listen(port);\n\n // Handle server listening event\n server.on(\"listening\", () => {\n Log.debug(`Server listening on port ${port}`);\n // Track that the server is running\n this.#running = true;\n });\n\n // Handle EADDRINUSE errors\n server.on(\"error\", (e: { code: string }) => {\n if (e.code === \"EADDRINUSE\") {\n Log.info(\n `Address in use, retrying in 2 seconds. If this persists, ensure ${port} is not in use, e.g. \"lsof -i :${port}\"`,\n );\n setTimeout(() => {\n server.close();\n server.listen(port);\n }, 2000);\n }\n });\n\n // Listen for the SIGTERM signal and gracefully close the server\n process.on(\"SIGTERM\", () => {\n Log.info(\"Received SIGTERM, closing server.\");\n server.close(() => {\n Log.info(\"Server closed.\");\n process.exit(143);\n });\n });\n };\n\n #bindEndpoints = (): void => {\n // Health check endpoint\n this.#app.get(\"/healthz\", Controller.#healthz);\n\n // Metrics endpoint\n this.#app.get(\"/metrics\", this.#metrics);\n\n if (isWatchMode()) {\n return;\n }\n\n // Require auth for webhook endpoints\n this.#app.use([\"/mutate/:path\", \"/validate/:path\"], this.#validatepath);\n\n // Mutate endpoint\n this.#app.post(\"/mutate/:path\", this.#admissionReq(\"Mutate\"));\n\n // Validate endpoint\n this.#app.post(\"/validate/:path\", this.#admissionReq(\"Validate\"));\n };\n\n /**\n * Validate the path in the request path\n *\n * @param req The incoming request\n * @param res The outgoing response\n * @param next The next middleware function\n * @returns\n */\n #validatepath = (req: express.Request, res: express.Response, next: NextFunction): void => {\n // Validate the path\n const { path } = req.params;\n if (path !== this.#path) {\n const err = `Unauthorized: invalid path '${path.replace(/[^\\w]/g, \"_\")}'`;\n Log.info(err);\n res.status(401).send(err);\n this.#metricsCollector.alert();\n return;\n }\n\n // path is valid, continue\n next();\n };\n\n /**\n * Metrics endpoint handler\n *\n * @param req the incoming request\n * @param res the outgoing response\n */\n #metrics = async (req: express.Request, res: express.Response): Promise<void> => {\n try {\n // https://github.com/prometheus/docs/blob/main/content/docs/instrumenting/exposition_formats.md#basic-info\n res.set(\"Content-Type\", \"text/plain; version=0.0.4\");\n res.send(await this.#metricsCollector.getMetrics());\n } catch (err) {\n Log.error(err, `Error getting metrics`);\n res.status(500).send(\"Internal Server Error\");\n }\n };\n\n /**\n * Admission request handler for both mutate and validate requests\n *\n * @param admissionKind the type of admission request\n * @returns the request handler\n */\n #admissionReq = (\n admissionKind: \"Mutate\" | \"Validate\",\n ): ((req: express.Request, res: express.Response) => Promise<void>) => {\n // Create the admission request handler\n return async (req: express.Request, res: express.Response) => {\n // Start the metrics timer\n const startTime = MetricsCollector.observeStart();\n\n try {\n // Get the request from the body or create an empty request\n const request: AdmissionRequest = req.body?.request || ({} as AdmissionRequest);\n\n const { name, namespace, gvk } = getRequestValues(request);\n\n const reqMetadata = { uid: request.uid, namespace, name };\n Log.info(\n { ...reqMetadata, gvk, operation: request.operation, admissionKind },\n \"Incoming request\",\n );\n Log.debug({ ...reqMetadata, request }, \"Incoming request body\");\n\n // Run the before hook if it exists\n if (typeof this.#beforeHook === \"function\") {\n this.#beforeHook(request || {});\n }\n\n // Process the request\n const response: MutateResponse | ValidateResponse[] =\n admissionKind === \"Mutate\"\n ? await mutateProcessor(this.#config, this.#capabilities, request, reqMetadata)\n : await validateProcessor(this.#config, this.#capabilities, request, reqMetadata);\n\n // Run the after hook if it exists\n [response].flat().map(res => {\n if (typeof this.#afterHook === \"function\") {\n this.#afterHook(res);\n }\n Log.info({ ...reqMetadata, res }, \"Check response\");\n });\n\n const kar: KubeAdmissionReview =\n admissionKind === \"Mutate\"\n ? karForMutate(response as MutateResponse)\n : karForValidate(request, response as ValidateResponse[]);\n\n Log.debug({ ...reqMetadata, kubeAdmissionResponse: kar.response }, \"Outgoing response\");\n res.send(kar);\n\n this.#metricsCollector.observeEnd(startTime, admissionKind);\n } catch (err) {\n Log.error(err, `Error processing ${admissionKind} request`);\n res.status(500).send(\"Internal Server Error\");\n this.#metricsCollector.error();\n }\n };\n };\n\n /**\n * Middleware for logging requests\n *\n * @param req the incoming request\n * @param res the outgoing response\n * @param next the next middleware function\n */\n static #logger(req: express.Request, res: express.Response, next: express.NextFunction): void {\n const startTime = Date.now();\n\n res.on(\"finish\", () => {\n const excludedRoutes = [\"/healthz\", \"/metrics\"];\n if (excludedRoutes.includes(req.originalUrl)) {\n return;\n }\n\n const elapsedTime = Date.now() - startTime;\n const message = {\n uid: req.body?.request?.uid,\n method: req.method,\n url: req.originalUrl,\n status: res.statusCode,\n duration: `${elapsedTime} ms`,\n };\n\n Log.info(message);\n });\n\n next();\n }\n /**\n * Health check endpoint handler\n *\n * @param req the incoming request\n * @param res the outgoing response\n */\n static #healthz(req: express.Request, res: express.Response): void {\n try {\n res.send(\"OK\");\n } catch (err) {\n Log.error(err, `Error processing health check`);\n res.status(500).send(\"Internal Server Error\");\n }\n }\n}\n\nfunction getRequestValues(request: AdmissionRequest): {\n name: string;\n namespace: string;\n gvk: GroupVersionKind;\n} {\n return {\n name: request?.name ? `/${request.name}` : \"\",\n namespace: request?.namespace || \"\",\n gvk: request?.kind || { group: \"\", version: \"\", kind: \"\" },\n };\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// SPDX-FileCopyrightText: 2023-Present The Pepr Authors\n\nimport { performance } from \"perf_hooks\";\nimport promClient, { Counter, Registry, Gauge, Summary } from \"prom-client\";\nimport Log from \"./logger\";\n\nconst loggingPrefix = \"MetricsCollector\";\n\nexport type MetricsCollectorInstance = InstanceType<typeof MetricsCollector>;\ninterface MetricNames {\n errors: string;\n alerts: string;\n mutate: string;\n validate: string;\n cacheMiss: string;\n resyncFailureCount: string;\n}\n\ninterface MetricArgs {\n name: string;\n help: string;\n registers: Registry[];\n labelNames?: string[];\n}\n\n/**\n * MetricsCollector class handles metrics collection using prom-client and performance hooks.\n */\nexport class MetricsCollector {\n #registry: Registry;\n #counters: Map<string, Counter<string>> = new Map();\n #gauges: Map<string, Gauge<string>> = new Map();\n #summaries: Map<string, Summary<string>> = new Map();\n #prefix: string;\n #cacheMissWindows: Map<string, number> = new Map();\n\n #metricNames: MetricNames = {\n errors: \"errors\",\n alerts: \"alerts\",\n mutate: \"mutate\",\n validate: \"validate\",\n cacheMiss: \"cache_miss\",\n resyncFailureCount: \"resync_failure_count\",\n };\n\n /**\n * Creates a MetricsCollector instance with prefixed metrics.\n * @param [prefix='pepr'] - The prefix for the metric names.\n */\n constructor(prefix = \"pepr\") {\n this.#registry = new Registry();\n this.#prefix = prefix;\n this.addCounter(this.#metricNames.errors, \"Mutation/Validate errors encountered\");\n this.addCounter(this.#metricNames.alerts, \"Mutation/Validate bad api path received\");\n this.addSummary(this.#metricNames.mutate, \"Mutation operation summary\");\n this.addSummary(this.#metricNames.validate, \"Validation operation summary\");\n this.addGauge(this.#metricNames.cacheMiss, \"Number of cache misses per window\", [\"window\"]);\n this.addGauge(this.#metricNames.resyncFailureCount, \"Number of failures per resync operation\", [\n \"count\",\n ]);\n }\n\n #getMetricName = (name: string): string => `${this.#prefix}_${name}`;\n\n #addMetric = <T extends Counter<string> | Gauge<string> | Summary<string>>(\n collection: Map<string, T>,\n MetricType: new (args: MetricArgs) => T,\n { name, help, labelNames }: Omit<MetricArgs, \"registers\">,\n ): void => {\n if (collection.has(this.#getMetricName(name))) {\n Log.debug({ loggingPrefix }, `Metric for ${name} already exists`);\n return;\n }\n\n const metric = new MetricType({\n name: this.#getMetricName(name),\n help,\n registers: [this.#registry],\n labelNames,\n });\n\n collection.set(this.#getMetricName(name), metric);\n };\n\n addCounter = (name: string, help: string): void => {\n this.#addMetric(this.#counters, promClient.Counter, { name, help, labelNames: [] });\n };\n\n addSummary = (name: string, help: string): void => {\n this.#addMetric(this.#summaries, promClient.Summary, { name, help, labelNames: [] });\n };\n\n addGauge = (name: string, help: string, labelNames?: string[]): void => {\n this.#addMetric(this.#gauges, promClient.Gauge, { name, help, labelNames });\n };\n\n incCounter = (name: string): void => {\n this.#counters.get(this.#getMetricName(name))?.inc();\n };\n\n incGauge = (name: string, labels?: Record<string, string>, value: number = 1): void => {\n this.#gauges.get(this.#getMetricName(name))?.inc(labels || {}, value);\n };\n\n /**\n * Increments the error counter.\n */\n error = (): void => this.incCounter(this.#metricNames.errors);\n\n /**\n * Increments the alerts counter.\n */\n alert = (): void => this.incCounter(this.#metricNames.alerts);\n\n /**\n * Observes the duration since the provided start time and updates the summary.\n * @param startTime - The start time.\n * @param name - The metrics summary to increment.\n */\n observeEnd = (startTime: number, name: string = this.#metricNames.mutate): void => {\n this.#summaries.get(this.#getMetricName(name))?.observe(performance.now() - startTime);\n };\n\n /**\n * Fetches the current metrics from the registry.\n * @returns The metrics.\n */\n getMetrics = (): Promise<string> => this.#registry.metrics();\n\n /**\n * Returns the current timestamp from performance.now() method. Useful for start timing an operation.\n * @returns The timestamp.\n */\n static observeStart(): number {\n return performance.now();\n }\n\n /**\n * Increments the cache miss gauge for a given label.\n * @param label - The label for the cache miss.\n */\n incCacheMiss = (window: string): void => {\n this.incGauge(this.#metricNames.cacheMiss, { window });\n };\n\n /**\n * Increments the retry count gauge.\n * @param count - The count to increment by.\n */\n incRetryCount = (count: number): void => {\n this.incGauge(this.#metricNames.resyncFailureCount, { count: count.toString() });\n };\n\n /**\n * Initializes the cache miss gauge for a given label.\n * @param label - The label for the cache miss.\n */\n initCacheMissWindow = (window: string): void => {\n this.#rollCacheMissWindows();\n this.#gauges.get(this.#getMetricName(this.#metricNames.cacheMiss))?.set({ window }, 0);\n this.#cacheMissWindows.set(window, 0);\n };\n\n /**\n * Manages the size of the cache miss gauge map.\n */\n #rollCacheMissWindows = (): void => {\n const maxCacheMissWindows = process.env.PEPR_MAX_CACHE_MISS_WINDOWS\n ? parseInt(process.env.PEPR_MAX_CACHE_MISS_WINDOWS, 10)\n : undefined;\n\n if (maxCacheMissWindows !== undefined && this.#cacheMissWindows.size >= maxCacheMissWindows) {\n const firstKey = this.#cacheMissWindows.keys().next().value;\n if (firstKey !== undefined) {\n this.#cacheMissWindows.delete(firstKey);\n }\n this.#gauges\n .get(this.#getMetricName(this.#metricNames.cacheMiss))\n ?.remove({ window: firstKey });\n }\n };\n}\n\nexport const metricsCollector: MetricsCollectorInstance = new MetricsCollector(\"pepr\");\n", "// SPDX-License-Identifier: Apache-2.0\n// SPDX-FileCopyrightText: 2023-Present The Pepr Authors\n\nimport jsonPatch from \"fast-json-patch\";\nimport { KubernetesObject } from \"kubernetes-fluent-client\";\nimport { MeasureWebhookTimeout } from \"../telemetry/webhookTimeouts\";\nimport { Capability } from \"../core/capability\";\nimport { shouldSkipRequest } from \"../filter/filter\";\nimport { MutateResponse } from \"../k8s\";\nimport { Binding } from \"../types\";\nimport Log from \"../telemetry/logger\";\nimport { ModuleConfig } from \"../types\";\nimport { PeprMutateRequest } from \"../mutate-request\";\nimport { base64Encode } from \"../utils\";\nimport { OnError } from \"../../cli/init/enums\";\nimport { getIgnoreNamespaces } from \"../assets/ignoredNamespaces\";\nimport { Operation } from \"fast-json-patch\";\nimport { WebhookType } from \"../enums\";\n\nimport { AdmissionRequest } from \"../common-types\";\n\nimport { decodeData, reencodeData } from \"./decode-utils\";\n\nexport interface Bindable {\n req: AdmissionRequest;\n config: ModuleConfig;\n name: string;\n namespaces: string[];\n binding: Binding;\n actMeta: Record<string, string>;\n}\n\ninterface Result {\n wrapped: PeprMutateRequest<KubernetesObject>;\n response: MutateResponse;\n}\n\n// Add annotations to the request to indicate that the capability started processing\n// this will allow tracking of failed mutations that were permitted to continue\nexport function updateStatus(\n config: ModuleConfig,\n name: string,\n wrapped: PeprMutateRequest<KubernetesObject>,\n status: string,\n): PeprMutateRequest<KubernetesObject> {\n // Only update the status if the request is a CREATE or UPDATE (we don't use CONNECT)\n if (wrapped.Request.operation === \"DELETE\") {\n return wrapped;\n }\n wrapped.SetAnnotation(`${config.uuid}.pepr.dev/${name}`, status);\n\n return wrapped;\n}\n\nexport function logMutateErrorMessage(e: Error): string {\n try {\n if (e.message && e.message !== \"[object Object]\") {\n return e.message;\n } else {\n throw new Error(\"An error occurred in the mutate action.\");\n }\n } catch {\n return \"An error occurred with the mutate action.\";\n }\n}\n\nexport async function processRequest(\n bindable: Bindable,\n wrapped: PeprMutateRequest<KubernetesObject>,\n response: MutateResponse,\n): Promise<Result> {\n const { binding, actMeta, name, config } = bindable;\n\n const label = binding.mutateCallback!.name;\n Log.info(actMeta, `Processing mutation action (${label})`);\n\n wrapped = updateStatus(config, name, wrapped, \"started\");\n\n try {\n // Run the action\n await binding.mutateCallback!(wrapped);\n\n // Log on success\n Log.info(actMeta, `Mutation action succeeded (${label})`);\n\n // Add annotations to the request to indicate that the capability succeeded\n wrapped = updateStatus(config, name, wrapped, \"succeeded\");\n } catch (e) {\n wrapped = updateStatus(config, name, wrapped, \"warning\");\n response.warnings = response.warnings || [];\n\n const errorMessage = logMutateErrorMessage(e);\n\n // Log on failure\n Log.error(actMeta, `Action failed: ${errorMessage}`);\n response.warnings.push(`Action failed: ${errorMessage}`);\n\n switch (config.onError) {\n case OnError.REJECT:\n response.result = \"Pepr module configured to reject on error\";\n break;\n\n case OnError.AUDIT:\n response.auditAnnotations = response.auditAnnotations || {};\n response.auditAnnotations[Date.now()] = `Action failed: ${errorMessage}`;\n break;\n }\n }\n\n return { wrapped, response };\n}\n\n/* eslint max-statements: [\"warn\", 25] */\nexport async function mutateProcessor(\n config: ModuleConfig,\n capabilities: Capability[],\n req: AdmissionRequest,\n reqMetadata: Record<string, string>,\n): Promise<MutateResponse> {\n const webhookTimer = new MeasureWebhookTimeout(WebhookType.MUTATE);\n webhookTimer.start(config.webhookTimeout);\n let response: MutateResponse = {\n uid: req.uid,\n warnings: [],\n allowed: false,\n };\n\n const decoded = decodeData(new PeprMutateRequest(req));\n let wrapped = decoded.wrapped;\n\n Log.info(reqMetadata, `Processing request`);\n const bindables: Bindable[] = capabilities\n .flatMap(capa =>\n capa.bindings.map(bind => ({\n req,\n config,\n name: capa.name,\n namespaces: capa.namespaces,\n binding: bind,\n actMeta: { ...reqMetadata, name: capa.name },\n })),\n )\n .filter(bind => {\n if (!bind.binding.mutateCallback) {\n return false;\n }\n\n const shouldSkip = shouldSkipRequest(\n bind.binding,\n bind.req,\n bind.namespaces,\n getIgnoreNamespaces(config),\n );\n if (shouldSkip !== \"\") {\n Log.debug(shouldSkip);\n return false;\n }\n\n return true;\n });\n\n for (const bindable of bindables) {\n ({ wrapped, response } = await processRequest(bindable, wrapped, response));\n if (config.onError === OnError.REJECT && response?.warnings!.length > 0) {\n webhookTimer.stop();\n return response;\n }\n }\n\n // The request is allowed\n\n // If no capability matched the request, exit early\n if (bindables.length === 0) {\n Log.info(reqMetadata, `No matching actions found`);\n webhookTimer.stop();\n return { ...response, allowed: true };\n }\n\n // delete operations can't be mutate, just return before the transformation\n if (req.operation === \"DELETE\") {\n webhookTimer.stop();\n return { ...response, allowed: true };\n }\n\n // unskip base64-encoded data fields that were skipDecode'd\n const transformed = reencodeData(wrapped, decoded.skipped);\n\n // Compare the original request to the modified request to get the patches\n const patches = jsonPatch.compare(req.object, transformed);\n\n updateResponsePatchAndWarnings(patches, response);\n\n Log.debug({ ...reqMetadata, patches }, `Patches generated`);\n webhookTimer.stop();\n return { ...response, allowed: true };\n}\n\nexport function updateResponsePatchAndWarnings(\n patches: Operation[],\n response: MutateResponse,\n): void {\n // Only add the patch if there are patches to apply\n if (patches.length > 0) {\n response.patchType = \"JSONPatch\";\n // Webhook must be base64-encoded\n // https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#response\n response.patch = base64Encode(JSON.stringify(patches));\n }\n\n // Remove the warnings array if it's empty\n if (response.warnings && response.warnings.length < 1) {\n delete response.warnings;\n }\n}\n", "export const getNow = (): number => performance.now();\n", "import { metricsCollector } from \"./metrics\";\nimport { getNow } from \"./timeUtils\";\nimport Log from \"./logger\";\nimport { WebhookType } from \"../enums\";\nexport class MeasureWebhookTimeout {\n #startTime: number | null = null;\n #webhookType: string;\n timeout: number = 0;\n\n constructor(webhookType: WebhookType) {\n this.#webhookType = webhookType;\n metricsCollector.addCounter(\n `${webhookType}_timeouts`,\n `Number of ${webhookType} webhook timeouts`,\n );\n }\n\n start(timeout: number = 10): void {\n this.#startTime = getNow();\n this.timeout = timeout;\n Log.debug(`Starting timer at ${this.#startTime}`);\n }\n\n stop(): void {\n if (this.#startTime === null) {\n throw new Error(\"Timer was not started before calling stop.\");\n }\n\n const elapsedTime = getNow() - this.#startTime;\n Log.debug(`Webhook ${this.#startTime} took ${elapsedTime}ms`);\n this.#startTime = null;\n\n if (elapsedTime > this.timeout) {\n metricsCollector.incCounter(`${this.#webhookType}_timeouts`);\n }\n }\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// SPDX-FileCopyrightText: 2023-Present The Pepr Authors\n\nimport { Operation } from \"../../enums\";\nimport { defaultTo, pipe } from \"ramda\";\nimport { KubernetesObject } from \"kubernetes-fluent-client\";\nimport { AdmissionRequest } from \"../../common-types\";\n\nexport const declaredOperation = pipe(\n (request: AdmissionRequest<KubernetesObject>): Operation => request?.operation,\n defaultTo(\"\"),\n);\nexport const declaredGroup = pipe(\n (request: AdmissionRequest<KubernetesObject>): string => request?.kind?.group,\n defaultTo(\"\"),\n);\nexport const declaredVersion = pipe(\n (request: AdmissionRequest<KubernetesObject>): string | undefined => request?.kind?.version,\n defaultTo(\"\"),\n);\nexport const declaredKind = pipe(\n (request: AdmissionRequest<KubernetesObject>): string => request?.kind?.kind,\n defaultTo(\"\"),\n);\nexport const declaredUid = pipe(\n (request: AdmissionRequest<KubernetesObject>): string => request?.uid,\n defaultTo(\"\"),\n);\n", "// SPDX-License-Identifier: Apache-2.0\n// SPDX-FileCopyrightText: 2023-Present The Pepr Authors\n\nimport { Event } from \"../../enums\";\nimport { Binding, FinalizeAction, WatchLogAction, MutateAction, ValidateAction } from \"../../types\";\nimport { complement, defaultTo, equals, not, pipe } from \"ramda\";\nimport { GenericClass } from \"kubernetes-fluent-client\";\n\nexport const definesDeletionTimestamp = pipe(\n (binding: Binding): boolean => binding?.filters?.deletionTimestamp ?? false,\n defaultTo(false),\n);\nexport const ignoresDeletionTimestamp = complement(definesDeletionTimestamp);\n\nexport const definedName = pipe((binding: Binding): string => {\n return binding.filters.name;\n}, defaultTo(\"\"));\nexport const definesName = pipe(definedName, equals(\"\"), not);\nexport const ignoresName = complement(definesName);\n\nexport const definedNameRegex = pipe(\n (binding: Partial<Binding>): string | undefined => binding.filters?.regexName,\n defaultTo(\"\"),\n);\nexport const definesNameRegex = pipe(definedNameRegex, equals(\"\"), not);\n\nexport const definedNamespaces = pipe(binding => binding?.filters?.namespaces, defaultTo([]));\nexport const definesNamespaces = pipe(definedNamespaces, equals([]), not);\n\nexport const definedNamespaceRegexes = pipe(\n binding => binding?.filters?.regexNamespaces,\n defaultTo([]),\n);\nexport const definesNamespaceRegexes = pipe(definedNamespaceRegexes, equals([]), not);\n\nexport const definedAnnotations = pipe(\n (binding: Partial<Binding>) => binding?.filters?.annotations,\n defaultTo({}),\n);\nexport const definesAnnotations = pipe(definedAnnotations, equals({}), not);\n\nexport const definedLabels = pipe(\n (binding: Partial<Binding>) => binding?.filters?.labels,\n defaultTo({}),\n);\nexport const definesLabels = pipe(definedLabels, equals({}), not);\n\nexport const definedEvent = (binding: Binding): Event => {\n return binding.event;\n};\n\nexport const definesDelete = (binding: Binding): boolean => definedEvent(binding) === Event.DELETE;\n\nexport const definedGroup = pipe((binding): string => binding?.kind?.group, defaultTo(\"\"));\nexport const definesGroup = pipe(definedGroup, equals(\"\"), not);\n\nexport const definedVersion = pipe(\n (binding: Partial<Binding>): string | undefined => binding?.kind?.version,\n defaultTo(\"\"),\n);\nexport const definesVersion = pipe(definedVersion, equals(\"\"), not);\n\nexport const definedKind = pipe((binding): string => binding?.kind?.kind, defaultTo(\"\"));\nexport const definesKind = pipe(definedKind, equals(\"\"), not);\n\nexport const definedCategory = (binding: Partial<Binding>): string => {\n // Ordering matters, finalize is a \"watch\"\n const categories: { [key: string]: boolean | undefined } = {\n Finalize: binding.isFinalize,\n Watch: binding.isWatch,\n Mutate: binding.isMutate,\n Validate: binding.isValidate,\n };\n\n return Object.keys(categories).find(key => categories[key]) || \"\";\n};\n\ntype DefinedCallbackReturnType =\n | FinalizeAction<GenericClass, InstanceType<GenericClass>>\n | WatchLogAction<GenericClass, InstanceType<GenericClass>>\n | MutateAction<GenericClass, InstanceType<GenericClass>>\n | ValidateAction<GenericClass, InstanceType<GenericClass>>\n | null\n | undefined;\n\nexport const definedCallback = (binding: Partial<Binding>): DefinedCallbackReturnType => {\n // Ordering matters, finalize is a \"watch\"\n // prettier-ignore\n return binding.isFinalize ? binding.finalizeCallback :\n binding.isWatch ? binding.watchCallback :\n binding.isMutate ? binding.mutateCallback :\n binding.isValidate ? binding.validateCallback :\n null;\n};\nexport const definedCallbackName = pipe(\n definedCallback,\n defaultTo({ name: \"\" }),\n callback => callback.name,\n);\n", "// SPDX-License-Identifier: Apache-2.0\n// SPDX-FileCopyrightText: 2023-Present The Pepr Authors\n\nimport { __, allPass, complement, defaultTo, equals, length, gt, not, nthArg, pipe } from \"ramda\";\nimport { KubernetesObject } from \"kubernetes-fluent-client\";\n\nconst carriesDeletionTimestamp = pipe(\n kubernetesObject => !!kubernetesObject.metadata?.deletionTimestamp,\n defaultTo(false),\n);\nexport const missingDeletionTimestamp = complement(carriesDeletionTimestamp);\n\nexport const carriedKind = pipe(\n (kubernetesObject: KubernetesObject): string | undefined => kubernetesObject?.kind,\n defaultTo(\"not set\"),\n);\nexport const carriedVersion = pipe(\n (kubernetesObject: KubernetesObject): string | undefined =>\n kubernetesObject?.metadata?.resourceVersion,\n defaultTo(\"not set\"),\n);\nexport const carriedName = pipe(\n (kubernetesObject: KubernetesObject): string | undefined => kubernetesObject?.metadata?.name,\n defaultTo(\"\"),\n);\nexport const carriesName = pipe(carriedName, equals(\"\"), not);\nexport const missingName = complement(carriesName);\n\nexport const carriedNamespace = pipe(\n (kubernetesObject: KubernetesObject): string | undefined => kubernetesObject?.metadata?.namespace,\n defaultTo(\"\"),\n);\n\nexport const carriesNamespace = pipe(carriedNamespace, equals(\"\"), not);\n\nexport const carriedAnnotations = pipe(\n (kubernetesObject: KubernetesObject): { [key: string]: string } | undefined =>\n kubernetesObject?.metadata?.annotations,\n defaultTo({}),\n);\nexport const carriesAnnotations = pipe(carriedAnnotations, equals({}), not);\n\nexport const carriedLabels = pipe(\n (kubernetesObject: KubernetesObject): { [key: string]: string } | undefined =>\n kubernetesObject?.metadata?.labels,\n defaultTo({}),\n);\nexport const carriesLabels = pipe(carriedLabels, equals({}), not);\n\n/*\n * If the object does not have a namespace, and it is not a namespace,\n * then we must return false because it cannot be uncarryable\n */\nexport const uncarryableNamespace = allPass([\n pipe(nthArg(0), length, gt(__, 0)),\n pipe((namespaceSelector, kubernetesObject) => {\n if (kubernetesObject?.kind === \"Namespace\") {\n return namespaceSelector.includes(kubernetesObject?.metadata?.name);\n }\n if (carriesNamespace(kubernetesObject)) {\n return namespaceSelector.includes(carriedNamespace(kubernetesObject));\n }\n return true;\n }, not),\n]);\n\n/*\n * Returns true if the object is missing a carriable namespace.\n * - If the object is a Namespace, it returns true if its name is not in the namespaceSelector.\n * - Otherwise, it returns true if the object does not carry a namespace.\n */\nexport const missingCarriableNamespace = allPass([\n pipe(nthArg(0), length, gt(__, 0)),\n pipe((namespaceSelector: string[], kubernetesObject: KubernetesObject): boolean =>\n kubernetesObject.kind === \"Namespace\"\n ? !namespaceSelector.includes(kubernetesObject.metadata!.name!)\n : !carriesNamespace(kubernetesObject),\n ),\n]);\n\n/*\n * If the object does not have a namespace, and it is not a namespace,\n * then we must return false because it cannot be ignored\n */\nexport const carriesIgnoredNamespace = allPass([\n pipe(nthArg(0), length, gt(__, 0)),\n pipe((namespaceSelector, kubernetesObject) => {\n if (kubernetesObject?.kind === \"Namespace\") {\n return namespaceSelector.includes(kubernetesObject?.metadata?.name);\n }\n if (carriesNamespace(kubernetesObject)) {\n return namespaceSelector.includes(carriedNamespace(kubernetesObject));\n }\n\n return false;\n }),\n]);\n", "// SPDX-License-Identifier: Apache-2.0\n// SPDX-FileCopyrightText: 2023-Present The Pepr Authors\n\nimport { Binding } from \"../../types\";\nimport { allPass, any, anyPass, equals, not, nthArg, pipe } from \"ramda\";\nimport {\n definedAnnotations,\n definedEvent,\n definedGroup,\n definedKind,\n definedLabels,\n definedName,\n definedNameRegex,\n definedNamespaceRegexes,\n definedNamespaces,\n definedVersion,\n definesAnnotations,\n definesDeletionTimestamp,\n definesGroup,\n definesKind,\n definesLabels,\n definesName,\n definesNameRegex,\n definesNamespaceRegexes,\n definesNamespaces,\n definesVersion,\n} from \"./binding\";\nimport {\n carriedAnnotations,\n carriedLabels,\n carriedName,\n carriedNamespace,\n missingDeletionTimestamp,\n} from \"./kubernetesObject\";\nimport {\n declaredOperation,\n declaredGroup,\n declaredVersion,\n declaredKind,\n} from \"./admissionRequest\";\nimport { Event, Operation } from \"../../enums\";\nimport { AdmissionRequest } from \"../../common-types\";\n\nexport const mismatchedDeletionTimestamp = allPass([\n pipe(nthArg(0), definesDeletionTimestamp),\n pipe(nthArg(1), missingDeletionTimestamp),\n]);\n\nexport const mismatchedName = allPass([\n pipe(nthArg(0), definesName),\n pipe((binding, kubernetesObject) => definedName(binding) !== carriedName(kubernetesObject)),\n]);\n\nexport const mismatchedNameRegex = allPass([\n pipe(nthArg(0), definesNameRegex),\n pipe(\n (binding, kubernetesObject) =>\n new RegExp(definedNameRegex(binding)).test(carriedName(kubernetesObject)),\n not,\n ),\n]);\n\nexport const mismatchedNamespace = allPass([\n pipe(nthArg(0), definesNamespaces),\n pipe(\n (binding, kubernetesObject) =>\n definedNamespaces(binding).includes(carriedNamespace(kubernetesObject)),\n not,\n ),\n]);\n\nexport const mismatchedNamespaceRegex = allPass([\n pipe(nthArg(0), definesNamespaceRegexes),\n pipe((binding, kubernetesObject) =>\n pipe(\n any((regEx: string) => new RegExp(regEx).test(carriedNamespace(kubernetesObject))),\n not,\n )(definedNamespaceRegexes(binding)),\n ),\n]);\n\nexport const metasMismatch = pipe(\n (defined, carried) => {\n const result = { defined, carried, unalike: {} };\n\n result.unalike = Object.entries(result.defined)\n .map(([key, value]) => {\n const keyMissing = !Object.hasOwn(result.carried, key);\n const noValue = !value;\n const valMissing = !result.carried[key];\n const valDiffers = result.carried[key] !== result.defined[key];\n\n // prettier-ignore\n return (\n keyMissing ? { [key]: value } :\n noValue ? {} :\n valMissing ? { [key]: value } :\n valDiffers ? { [key]: value } :\n {}\n )\n })\n .reduce((acc, cur) => ({ ...acc, ...cur }), {});\n\n return result.unalike;\n },\n unalike => Object.keys(unalike).length > 0,\n);\n\nexport const mismatchedAnnotations = allPass([\n pipe(nthArg(0), definesAnnotations),\n pipe((binding, kubernetesObject) =>\n metasMismatch(definedAnnotations(binding), carriedAnnotations(kubernetesObject)),\n ),\n]);\n\nexport const mismatchedLabels = allPass([\n pipe(nthArg(0), definesLabels),\n pipe((binding, kubernetesObject) =>\n metasMismatch(definedLabels(binding), carriedLabels(kubernetesObject)),\n ),\n]);\n\nexport const mismatchedEvent = pipe(\n (binding: Binding, request: AdmissionRequest): boolean =>\n operationMatchesEvent(declaredOperation(request), definedEvent(binding)),\n not,\n);\n\nexport const mismatchedGroup = allPass([\n pipe(nthArg(0), definesGroup),\n pipe((binding, request) => definedGroup(binding) !== declaredGroup(request)),\n]);\n\nexport const mismatchedVersion = allPass([\n pipe(nthArg(0), definesVersion),\n pipe((binding, request) => definedVersion(binding) !== declaredVersion(request)),\n]);\n\nexport const mismatchedKind = allPass([\n pipe(nthArg(0), definesKind),\n pipe((binding, request) => definedKind(binding) !== declaredKind(request)),\n]);\nexport const operationMatchesEvent = anyPass([\n pipe(nthArg(1), equals(Event.ANY)),\n pipe((operation: Operation, event: Event): boolean => operation.valueOf() === event.valueOf()),\n pipe((operation: Operation, event: Event): boolean =>\n operation ? event.includes(operation) : false,\n ),\n]);\n", "// SPDX-License-Identifier: Apache-2.0\n// SPDX-FileCopyrightText: 2023-Present The Pepr Authors\n\nimport { __, allPass, curry, difference, equals, gt, length, not, nthArg, pipe } from \"ramda\";\nimport { KubernetesObject } from \"kubernetes-fluent-client\";\nimport {\n definedKind,\n definedNamespaces,\n definesDelete,\n definesDeletionTimestamp,\n definesNamespaces,\n} from \"./binding\";\nimport { carriedNamespace, carriesNamespace } from \"./kubernetesObject\";\n\n/*\n Naming scheme:\n - AdmissionRequest - \"declares\" / \"neglects\"\n - KubernetesObject - \"carries\" / \"missing\"\n - Binding - \"defines\" / \"ignores\"\n*/\n\nexport const bindsToKind = curry(\n allPass([\n pipe(nthArg(0), definedKind, equals(\"\"), not),\n pipe((binding, kind) => definedKind(binding) === kind),\n ]),\n);\nexport const bindsToNamespace = curry(pipe(bindsToKind(__, \"Namespace\")));\nexport const misboundNamespace = allPass([bindsToNamespace, definesNamespaces]);\n\n/*\n * If the object does not have a namespace, and it is not a namespace,\n * then we must return false because it cannot be uncarryable\n */\nexport const uncarryableNamespace = allPass([\n pipe(nthArg(0), length, gt(__, 0)),\n pipe((namespaceSelector, kubernetesObject) => {\n if (kubernetesObject?.kind === \"Namespace\") {\n return namespaceSelector.includes(kubernetesObject?.metadata?.name);\n }\n if (carriesNamespace(kubernetesObject)) {\n return namespaceSelector.includes(carriedNamespace(kubernetesObject));\n }\n return true;\n }, not),\n]);\n\nexport const missingCarriableNamespace = allPass([\n pipe(nthArg(0), length, gt(__, 0)),\n pipe((namespaceSelector: string[], kubernetesObject: KubernetesObject): boolean =>\n kubernetesObject.kind === \"Namespace\"\n ? !namespaceSelector.includes(kubernetesObject.metadata!.name!)\n : !carriesNamespace(kubernetesObject),\n ),\n]);\n\n/*\n * If the object does not have a namespace, and it is not a namespace,\n * then we must return false because it cannot be ignored\n */\nexport const carriesIgnoredNamespace = allPass([\n pipe(nthArg(0), length, gt(__, 0)),\n pipe((namespaceSelector, kubernetesObject) => {\n if (kubernetesObject?.kind === \"Namespace\") {\n return namespaceSelector.includes(kubernetesObject?.metadata?.name);\n }\n if (carriesNamespace(kubernetesObject)) {\n return namespaceSelector.includes(carriedNamespace(kubernetesObject));\n }\n\n return false;\n }),\n]);\n\nexport const unbindableNamespaces = allPass([\n pipe(nthArg(0), length, gt(__, 0)),\n pipe(nthArg(1), definesNamespaces),\n pipe(\n (namespaceSelector, binding) => difference(definedNamespaces(binding), namespaceSelector),\n length,\n equals(0),\n not,\n ),\n]);\n\nexport const misboundDeleteWithDeletionTimestamp = allPass([\n definesDelete,\n definesDeletionTimestamp,\n]);\n", "import { KubernetesObject } from \"kubernetes-fluent-client\";\nimport { AdmissionRequest } from \"../common-types\";\nimport { Binding } from \"../types\";\nimport {\n declaredOperation,\n declaredGroup,\n declaredVersion,\n declaredKind,\n} from \"./adjudicators/admissionRequest\";\nimport {\n definedEvent,\n definedName,\n definedGroup,\n definedVersion,\n definedKind,\n definedNamespaces,\n definedLabels,\n definedAnnotations,\n definedNamespaceRegexes,\n definedNameRegex,\n} from \"./adjudicators/binding\";\nimport {\n carriedName,\n carriedNamespace,\n carriedLabels,\n carriedAnnotations,\n} from \"./adjudicators/kubernetesObject\";\nimport {\n mismatchedDeletionTimestamp,\n mismatchedEvent,\n mismatchedName,\n mismatchedGroup,\n mismatchedVersion,\n mismatchedKind,\n mismatchedNamespace,\n mismatchedLabels,\n mismatchedAnnotations,\n mismatchedNamespaceRegex,\n mismatchedNameRegex,\n} from \"./adjudicators/mismatch\";\nimport {\n misboundNamespace,\n misboundDeleteWithDeletionTimestamp,\n unbindableNamespaces,\n uncarryableNamespace,\n carriesIgnoredNamespace,\n missingCarriableNamespace,\n} from \"./adjudicators/postCollection\";\nimport { AdjudicationResult } from \"../types\";\n\nexport function adjudicateMisboundNamespace(binding: Binding): AdjudicationResult {\n return misboundNamespace(binding) ? \"Cannot use namespace filter on a namespace object.\" : null;\n}\n\nexport function adjudicateMisboundDeleteWithDeletionTimestamp(\n binding: Binding,\n): AdjudicationResult {\n return misboundDeleteWithDeletionTimestamp(binding)\n ? \"Cannot use deletionTimestamp filter on a DELETE operation.\"\n : null;\n}\n\nexport function adjudicateMismatchedDeletionTimestamp(\n binding: Binding,\n obj: KubernetesObject,\n): AdjudicationResult {\n return mismatchedDeletionTimestamp(binding, obj)\n ? \"Binding defines deletionTimestamp but Object does not carry it.\"\n : null;\n}\n\nexport function adjudicateMismatchedEvent(\n binding: Binding,\n req: AdmissionRequest,\n): AdjudicationResult {\n return mismatchedEvent(binding, req)\n ? `Binding defines event '${definedEvent(binding)}' but Request declares '${declaredOperation(req)}'.`\n : null;\n}\n\nexport function adjudicateMismatchedName(\n binding: Binding,\n obj: KubernetesObject,\n): AdjudicationResult {\n return mismatchedName(binding, obj)\n ? `Binding defines name '${definedName(binding)}' but Object carries '${carriedName(obj)}'.`\n : null;\n}\n\nexport function adjudicateMismatchedGroup(\n binding: Binding,\n req: AdmissionRequest,\n): AdjudicationResult {\n return mismatchedGroup(binding, req)\n ? `Binding defines group '${definedGroup(binding)}' but Request declares '${declaredGroup(req)}'.`\n : null;\n}\n\nexport function adjudicateMismatchedVersion(\n binding: Binding,\n req: AdmissionRequest,\n): AdjudicationResult {\n return mismatchedVersion(binding, req)\n ? `Binding defines version '${definedVersion(binding)}' but Request declares '${declaredVersion(req)}'.`\n : null;\n}\n\nexport function adjudicateMismatchedKind(\n binding: Binding,\n req: AdmissionRequest,\n): AdjudicationResult {\n return mismatchedKind(binding, req)\n ? `Binding defines kind '${definedKind(binding)}' but Request declares '${declaredKind(req)}'.`\n : null;\n}\n\nexport function adjudicateUnbindableNamespaces(\n capabilityNamespaces: string[],\n binding: Binding,\n): AdjudicationResult {\n return unbindableNamespaces(capabilityNamespaces, binding)\n ? `Binding defines namespaces ${JSON.stringify(definedNamespaces(binding))} but namespaces allowed by Capability are '${JSON.stringify(capabilityNamespaces)}'.`\n : null;\n}\n\nexport function adjudicateUncarryableNamespace(\n capabilityNamespaces: string[],\n obj: KubernetesObject,\n): AdjudicationResult {\n return uncarryableNamespace(capabilityNamespaces, obj)\n ? `Object carries namespace '${obj.kind && obj.kind === \"Namespace\" ? obj.metadata?.name : carriedNamespace(obj)}' but namespaces allowed by Capability are '${JSON.stringify(capabilityNamespaces)}'.`\n : null;\n}\n\nexport function adjudicateMismatchedNamespace(\n binding: Binding,\n obj: KubernetesObject,\n): AdjudicationResult {\n return mismatchedNamespace(binding, obj)\n ? `Binding defines namespaces '${JSON.stringify(definedNamespaces(binding))}' but Object carries '${carriedNamespace(obj)}'.`\n : null;\n}\n\nexport function adjudicateMismatchedLabels(\n binding: Binding,\n obj: KubernetesObject,\n): AdjudicationResult {\n return mismatchedLabels(binding, obj)\n ? `Binding defines labels '${JSON.stringify(definedLabels(binding))}' but Object carries '${JSON.stringify(carriedLabels(obj))}'.`\n : null;\n}\n\nexport function adjudicateMismatchedAnnotations(\n binding: Binding,\n obj: KubernetesObject,\n): AdjudicationResult {\n return mismatchedAnnotations(binding, obj)\n ? `Binding defines annotations '${JSON.stringify(definedAnnotations(binding))}' but Object carries '${JSON.stringify(carriedAnnotations(obj))}'.`\n : null;\n}\n\nexport function adjudicateMismatchedNamespaceRegex(\n binding: Binding,\n obj: KubernetesObject,\n): AdjudicationResult {\n return mismatchedNamespaceRegex(binding, obj)\n ? `Binding defines namespace regexes '${JSON.stringify(definedNamespaceRegexes(binding))}' but Object carries '${carriedNamespace(obj)}'.`\n : null;\n}\n\nexport function adjudicateMismatchedNameRegex(\n binding: Binding,\n obj: KubernetesObject,\n): AdjudicationResult {\n return mismatchedNameRegex(binding, obj)\n ? `Binding defines name regex '${definedNameRegex(binding)}' but Object carries '${carriedName(obj)}'.`\n : null;\n}\n\nexport function adjudicateCarriesIgnoredNamespace(\n ignoredNamespaces: string[] | undefined,\n obj: KubernetesObject,\n): AdjudicationResult {\n return carriesIgnoredNamespace(ignoredNamespaces, obj)\n ? `Object carries namespace '${obj.kind && obj.kind === \"Namespace\" ? obj.metadata?.name : carriedNamespace(obj)}' but ignored namespaces include '${JSON.stringify(ignoredNamespaces)}'.`\n : null;\n}\n\nexport function adjudicateMissingCarriableNamespace(\n capabilityNamespaces: string[],\n obj: KubernetesObject,\n): AdjudicationResult {\n return missingCarriableNamespace(capabilityNamespaces, obj)\n ? `Object does not carry a namespace but namespaces allowed by Capability are '${JSON.stringify(capabilityNamespaces)}'.`\n : null;\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// SPDX-FileCopyrightText: 2023-Present The Pepr Authors\n\nimport { AdjudicationResult, Binding } from \"../types\";\nimport { Operation } from \"../enums\";\nimport { KubernetesObject } from \"kubernetes-fluent-client\";\nimport { AdmissionRequest } from \"../common-types\";\nimport {\n adjudicateMisboundDeleteWithDeletionTimestamp,\n adjudicateMismatchedDeletionTimestamp,\n adjudicateMismatchedEvent,\n adjudicateMismatchedName,\n adjudicateMismatchedGroup,\n adjudicateMismatchedVersion,\n adjudicateMismatchedKind,\n adjudicateUnbindableNamespaces,\n adjudicateUncarryableNamespace,\n adjudicateMismatchedNamespace,\n adjudicateMismatchedLabels,\n adjudicateMismatchedAnnotations,\n adjudicateMismatchedNamespaceRegex,\n adjudicateMismatchedNameRegex,\n adjudicateCarriesIgnoredNamespace,\n adjudicateMissingCarriableNamespace,\n adjudicateMisboundNamespace,\n} from \"./adjudication\";\n\ntype Adjudicator = () => AdjudicationResult;\n\n/**\n * shouldSkipRequest determines if an admission request should be skipped based on the binding filters.\n *\n * @param binding the action binding\n * @param req the incoming request\n * @param capabilityNamespaces the namespaces allowed by capability\n * @param ignoredNamespaces the namespaces ignored by module config\n * @returns\n */\nexport function shouldSkipRequest(\n binding: Binding,\n req: AdmissionRequest,\n capabilityNamespaces: string[],\n ignoredNamespaces?: string[],\n): string {\n const obj = (req.operation === Operation.DELETE ? req.oldObject : req.object)!;\n const prefix = \"Ignoring Admission Callback:\";\n\n const adjudicators: Adjudicator[] = [\n (): AdjudicationResult => adjudicateMisboundDeleteWithDeletionTimestamp(binding),\n (): AdjudicationResult => adjudicateMismatchedDeletionTimestamp(binding, obj),\n (): AdjudicationResult => adjudicateMismatchedEvent(binding, req),\n (): AdjudicationResult => adjudicateMismatchedName(binding, obj),\n (): AdjudicationResult => adjudicateMismatchedGroup(binding, req),\n (): AdjudicationResult => adjudicateMismatchedVersion(binding, req),\n (): AdjudicationResult => adjudicateMismatchedKind(binding, req),\n (): AdjudicationResult => adjudicateUnbindableNamespaces(capabilityNamespaces, binding),\n (): AdjudicationResult => adjudicateUncarryableNamespace(capabilityNamespaces, obj),\n (): AdjudicationResult => adjudicateMismatchedNamespace(binding, obj),\n (): AdjudicationResult => adjudicateMismatchedLabels(binding, obj),\n (): AdjudicationResult => adjudicateMismatchedAnnotations(binding, obj),\n (): AdjudicationResult => adjudicateMismatchedNamespaceRegex(binding, obj),\n (): AdjudicationResult => adjudicateMismatchedNameRegex(binding, obj),\n (): AdjudicationResult => adjudicateCarriesIgnoredNamespace(ignoredNamespaces, obj),\n (): AdjudicationResult => adjudicateMissingCarriableNamespace(capabilityNamespaces, obj),\n ];\n\n for (const adjudicator of adjudicators) {\n const result = adjudicator();\n if (result) {\n return `${prefix} ${result}`;\n }\n }\n\n return \"\";\n}\n\n/**\n * filterNoMatchReason determines whether a callback should be skipped after\n * receiving an update event from the API server, based on the binding filters.\n *\n * @param binding the action binding\n * @param kubernetesObject the incoming kubernetes object\n * @param capabilityNamespaces the namespaces allowed by capability\n * @param ignoredNamespaces the namespaces ignored by module config\n */\nexport function filterNoMatchReason(\n binding: Binding,\n obj: Partial<KubernetesObject>,\n capabilityNamespaces: string[],\n ignoredNamespaces?: string[],\n): string {\n const prefix = \"Ignoring Watch Callback:\";\n\n const adjudicators: Adjudicator[] = [\n (): AdjudicationResult => adjudicateMismatchedDeletionTimestamp(binding, obj),\n (): AdjudicationResult => adjudicateMismatchedName(binding, obj),\n (): AdjudicationResult => adjudicateMisboundNamespace(binding),\n (): AdjudicationResult => adjudicateMismatchedLabels(binding, obj),\n (): AdjudicationResult => adjudicateMismatchedAnnotations(binding, obj),\n (): AdjudicationResult => adjudicateUncarryableNamespace(capabilityNamespaces, obj),\n (): AdjudicationResult => adjudicateUnbindableNamespaces(capabilityNamespaces, binding),\n (): AdjudicationResult => adjudicateMismatchedNamespace(binding, obj),\n (): AdjudicationResult => adjudicateMismatchedNamespaceRegex(binding, obj),\n (): AdjudicationResult => adjudicateMismatchedNameRegex(binding, obj),\n (): AdjudicationResult => adjudicateCarriesIgnoredNamespace(ignoredNamespaces, obj),\n (): AdjudicationResult => adjudicateMissingCarriableNamespace(capabilityNamespaces, obj),\n ];\n\n for (const adjudicator of adjudicators) {\n const result = adjudicator();\n if (result) {\n return `${prefix} ${result}`;\n }\n }\n\n return \"\";\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// SPDX-FileCopyrightText: 2023-Present The Pepr Authors\n\nimport { Operation } from \"./enums\";\nimport { KubernetesObject } from \"kubernetes-fluent-client\";\nimport { clone, mergeDeepRight } from \"ramda\";\nimport { AdmissionRequest } from \"./common-types\";\nimport { DeepPartial } from \"./common-types\";\n\n// PeprMutateRequest class for mutation request handling\nexport class PeprMutateRequest<T extends KubernetesObject> {\n Raw: T;\n #input: AdmissionRequest<T>;\n\n get PermitSideEffects(): boolean {\n return !this.#input.dryRun;\n }\n\n get IsDryRun(): boolean | undefined {\n return this.#input.dryRun;\n }\n\n get OldResource(): KubernetesObject | undefined {\n return this.#input.oldObject;\n }\n\n get Request(): AdmissionRequest<KubernetesObject> {\n return this.#input;\n }\n\n constructor(input: AdmissionRequest<T>) {\n this.#input = input;\n // If this is a DELETE operation, use the oldObject instead\n if (input.operation.toUpperCase() === Operation.DELETE) {\n this.Raw = clone(input.oldObject as T);\n } else {\n // Otherwise, use the incoming object\n this.Raw = clone(input.object);\n }\n\n if (!this.Raw) {\n throw new Error(\"Unable to load the request object into PeprRequest.Raw\");\n }\n }\n\n Merge = (obj: DeepPartial<T>): void => {\n this.Raw = mergeDeepRight(this.Raw, obj) as unknown as T;\n };\n\n SetLabel = (key: string, value: string): this => {\n const ref = this.Raw;\n ref.metadata = ref.metadata ?? {};\n ref.metadata.labels = ref.metadata.labels ?? {};\n ref.metadata.labels[key] = value;\n return this;\n };\n\n SetAnnotation = (key: string, value: string): this => {\n const ref = this.Raw;\n ref.metadata = ref.metadata ?? {};\n ref.metadata.annotations = ref.metadata.annotations ?? {};\n ref.metadata.annotations[key] = value;\n return this;\n };\n\n RemoveLabel = (key: string): this => {\n if (this.Raw.metadata?.labels?.[key]) {\n delete this.Raw.metadata.labels[key];\n }\n return this;\n };\n\n RemoveAnnotation = (key: string): this => {\n if (this.Raw.metadata?.annotations?.[key]) {\n delete this.Raw.metadata.annotations[key];\n }\n return this;\n };\n\n HasLabel = (key: string): boolean => {\n return this.Raw.metadata?.labels?.[key] !== undefined;\n };\n\n HasAnnotation = (key: string): boolean => {\n return this.Raw.metadata?.annotations?.[key] !== undefined;\n };\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// SPDX-FileCopyrightText: 2023-Present The Pepr Authors\n\nimport Log from \"./telemetry/logger\";\n\n/** Test if a string is ascii or not */\nexport const isAscii: RegExp = /^[\\s\\x20-\\x7E]*$/;\n\n/**\n * Encode all ascii values in a map to base64\n * @param obj The object to encode\n * @param skip A list of keys to skip encoding\n */\nexport function convertToBase64Map(obj: { data?: Record<string, string> }, skip: string[]): void {\n obj.data = obj.data ?? {};\n for (const key in obj.data) {\n const value = obj.data[key];\n // Only encode ascii values\n obj.data[key] = skip.includes(key) ? value : base64Encode(value);\n }\n}\n\n/**\n * Decode all ascii values in a map from base64 to utf-8\n * @param obj The object to decode\n * @returns A list of keys that were skipped\n */\nexport function convertFromBase64Map(obj: { data?: Record<string, string> }): string[] {\n const skip: string[] = [];\n\n obj.data = obj.data ?? {};\n for (const key in obj.data) {\n if (obj.data[key] === undefined) {\n obj.data[key] = \"\";\n } else {\n const decoded = base64Decode(obj.data[key]);\n if (isAscii.test(decoded)) {\n // Only decode ascii values\n obj.data[key] = decoded;\n } else {\n skip.push(key);\n }\n }\n }\n Log.debug(`Non-ascii data detected in keys: ${skip}, skipping automatic base64 decoding`);\n return skip;\n}\n\n/** Decode a base64 string */\nexport function base64Decode(data: string): string {\n return Buffer.from(data, \"base64\").toString(\"utf-8\");\n}\n\n/** Encode a string to base64 */\nexport function base64Encode(data: string): string {\n return Buffer.from(data).toString(\"base64\");\n}\n", "export enum RbacMode {\n SCOPED = \"scoped\",\n ADMIN = \"admin\",\n}\nexport enum OnError {\n AUDIT = \"audit\",\n IGNORE = \"ignore\",\n REJECT = \"reject\",\n}\n\nexport const UUID_LENGTH_LIMIT = 36;\n", "// SPDX-License-Identifier: Apache-2.0\n// SPDX-FileCopyrightText: 2023-Present The Pepr Authors\nimport { ModuleConfig } from \"../types\";\n\nexport function getIgnoreNamespaces(config?: ModuleConfig): string[] {\n const fromConfig = config?.alwaysIgnore?.namespaces?.length\n ? config.alwaysIgnore.namespaces\n : config?.admission?.alwaysIgnore?.namespaces;\n\n return resolveIgnoreNamespaces(fromConfig);\n}\n\nexport function resolveIgnoreNamespaces(ignoredNSConfig: string[] = []): string[] {\n const ignoredNSEnv = process.env.PEPR_ADDITIONAL_IGNORED_NAMESPACES;\n if (!ignoredNSEnv) {\n return ignoredNSConfig;\n }\n\n const namespaces = ignoredNSEnv.split(\",\").map(ns => ns.trim());\n\n // add alwaysIgnore.namespaces to the list\n if (ignoredNSConfig) {\n namespaces.push(...ignoredNSConfig);\n }\n return namespaces.filter(ns => ns.length > 0);\n}\n", "import { convertFromBase64Map, convertToBase64Map } from \"../utils\";\nimport { kind, KubernetesObject } from \"kubernetes-fluent-client\";\nimport { PeprMutateRequest } from \"../mutate-request\";\nimport { clone } from \"ramda\";\n\nexport function decodeData(wrapped: PeprMutateRequest<KubernetesObject>): {\n skipped: string[];\n wrapped: PeprMutateRequest<KubernetesObject>;\n} {\n let skipped: string[] = [];\n\n const isSecret = wrapped.Request.kind.version === \"v1\" && wrapped.Request.kind.kind === \"Secret\";\n if (isSecret) {\n // convertFromBase64Map modifies it's arg rather than returing a mod'ed copy (ye olde side-effect special, blerg)\n skipped = convertFromBase64Map(wrapped.Raw as unknown as kind.Secret);\n }\n\n return { skipped, wrapped };\n}\n\nexport function reencodeData(\n wrapped: PeprMutateRequest<KubernetesObject>,\n skipped: string[],\n): KubernetesObject {\n const transformed = clone(wrapped.Raw);\n\n const isSecret = wrapped.Request.kind.version === \"v1\" && wrapped.Request.kind.kind === \"Secret\";\n if (isSecret) {\n // convertToBase64Map modifies it's arg rather than returing a mod'ed copy (ye olde side-effect special, blerg)\n convertToBase64Map(transformed as unknown as kind.Secret, skipped);\n }\n\n return transformed;\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// SPDX-FileCopyrightText: 2023-Present The Pepr Authors\n\n/* eslint-disable class-methods-use-this */\n\nimport { KubernetesObject } from \"kubernetes-fluent-client\";\n\nimport { clone } from \"ramda\";\nimport { AdmissionRequest, ValidateActionResponse } from \"./common-types\";\nimport { Operation } from \"./enums\";\n\n/**\n * The RequestWrapper class provides methods to modify Kubernetes objects in the context\n * of a mutating webhook request.\n */\nexport class PeprValidateRequest<T extends KubernetesObject> {\n Raw: T;\n\n #input: AdmissionRequest<T>;\n\n /**\n * Provides access to the old resource in the request if available.\n * @returns The old Kubernetes resource object or null if not available.\n */\n get OldResource(): KubernetesObject | undefined {\n return this.#input.oldObject;\n }\n\n /**\n * Provides access to the request object.\n * @returns The request object containing the Kubernetes resource.\n */\n get Request(): AdmissionRequest<KubernetesObject> {\n return this.#input;\n }\n\n /**\n * Creates a new instance of the Action class.\n * @param input - The request object containing the Kubernetes resource to modify.\n */\n constructor(input: AdmissionRequest<T>) {\n this.#input = input;\n\n // If this is a DELETE operation, use the oldObject instead\n if (input.operation.toUpperCase() === Operation.DELETE) {\n this.Raw = clone(input.oldObject as T);\n } else {\n // Otherwise, use the incoming object\n this.Raw = clone(input.object);\n }\n\n if (!this.Raw) {\n throw new Error(\"unable to load the request object into PeprRequest.Raw\");\n }\n }\n\n /**\n * Check if a label exists on the Kubernetes resource.\n *\n * @param key the label key to check\n * @returns\n */\n HasLabel = (key: string): boolean => {\n return this.Raw.metadata?.labels?.[key] !== undefined;\n };\n\n /**\n * Check if an annotation exists on the Kubernetes resource.\n *\n * @param key the annotation key to check\n * @returns\n */\n HasAnnotation = (key: string): boolean => {\n return this.Raw.metadata?.annotations?.[key] !== undefined;\n };\n\n /**\n * Create a validation response that allows the request.\n *\n * @returns The validation response.\n */\n Approve = (warnings?: string[]): ValidateActionResponse => {\n return {\n allowed: true,\n warnings,\n };\n };\n\n /**\n * Create a validation response that denies the request.\n *\n * @param statusMessage Optional status message to return to the user.\n * @param statusCode Optional status code to return to the user.\n * @returns The validation response.\n */\n Deny = (\n statusMessage?: string,\n statusCode?: number,\n warnings?: string[],\n ): ValidateActionResponse => {\n return {\n allowed: false,\n statusCode,\n statusMessage,\n warnings,\n };\n };\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// SPDX-FileCopyrightText: 2023-Present The Pepr Authors\n\nimport { kind, KubernetesObject } from \"kubernetes-fluent-client\";\nimport { Capability } from \"../core/capability\";\nimport { shouldSkipRequest } from \"../filter/filter\";\nimport { ValidateResponse } from \"../k8s\";\nimport { Binding } from \"../types\";\nimport Log from \"../telemetry/logger\";\nimport { convertFromBase64Map } from \"../utils\";\nimport { PeprValidateRequest } from \"../validate-request\";\nimport { ModuleConfig } from \"../types\";\nimport { getIgnoreNamespaces } from \"../assets/ignoredNamespaces\";\nimport { MeasureWebhookTimeout } from \"../telemetry/webhookTimeouts\";\nimport { WebhookType } from \"../enums\";\nimport { AdmissionRequest } from \"../common-types\";\n\nexport async function processRequest(\n binding: Binding,\n actionMetadata: Record<string, string>,\n peprValidateRequest: PeprValidateRequest<KubernetesObject>,\n): Promise<ValidateResponse> {\n const label = binding.validateCallback!.name;\n Log.info(actionMetadata, `Processing validation action (${label})`);\n\n const valResp: ValidateResponse = {\n uid: peprValidateRequest.Request.uid,\n allowed: true, // Assume it's allowed until a validation check fails\n };\n\n try {\n // Run the validation callback, if it fails set allowed to false\n const callbackResp = await binding.validateCallback!(peprValidateRequest);\n valResp.allowed = callbackResp.allowed;\n\n // If the validation callback returned a status code or message, set it in the Response\n if (callbackResp.statusCode || callbackResp.statusMessage) {\n valResp.status = {\n code: callbackResp.statusCode || 400,\n message:\n callbackResp.statusMessage ||\n `Validation failed for ${peprValidateRequest.Request.kind.kind.toLowerCase()}/${peprValidateRequest.Request.name}${peprValidateRequest.Request.namespace ? ` in ${peprValidateRequest.Request.namespace} namespace.` : \"\"}`,\n };\n }\n\n // Transfer any warnings from the callback response to the validation response\n if (callbackResp.warnings && callbackResp.warnings.length > 0) {\n valResp.warnings = callbackResp.warnings;\n }\n\n Log.info(\n actionMetadata,\n `Validation action complete (${label}): ${callbackResp.allowed ? \"allowed\" : \"denied\"}`,\n );\n return valResp;\n } catch (e) {\n // If any validation throws an error, note the failure in the Response\n Log.error(actionMetadata, `Action failed: ${JSON.stringify(e)}`);\n valResp.allowed = false;\n valResp.status = {\n code: 500,\n message: `Action failed with error: ${JSON.stringify(e)}`,\n };\n return valResp;\n }\n}\n\nexport async function validateProcessor(\n config: ModuleConfig,\n capabilities: Capability[],\n req: AdmissionRequest,\n reqMetadata: Record<string, string>,\n): Promise<ValidateResponse[]> {\n const webhookTimer = new MeasureWebhookTimeout(WebhookType.VALIDATE);\n webhookTimer.start(config.webhookTimeout);\n const wrapped = new PeprValidateRequest(req);\n const response: ValidateResponse[] = [];\n\n // If the resource is a secret, decode the data\n if (req.kind.version === \"v1\" && req.kind.kind === \"Secret\") {\n convertFromBase64Map(wrapped.Raw as unknown as kind.Secret);\n }\n\n Log.info(reqMetadata, `Processing validation request`);\n\n for (const { name, bindings, namespaces } of capabilities) {\n const actionMetadata = { ...reqMetadata, name };\n\n for (const binding of bindings) {\n // Skip this action if it's not a validation action\n if (!binding.validateCallback) {\n continue;\n }\n\n // Continue to the next action without doing anything if this one should be skipped\n const shouldSkip = shouldSkipRequest(binding, req, namespaces, getIgnoreNamespaces(config));\n if (shouldSkip !== \"\") {\n Log.debug(shouldSkip);\n continue;\n }\n\n const resp = await processRequest(binding, actionMetadata, wrapped);\n response.push(resp);\n }\n }\n webhookTimer.stop();\n return response;\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// SPDX-FileCopyrightText: 2023-Present The Pepr Authors\n\nimport { Operation } from \"fast-json-patch\";\nimport { K8s } from \"kubernetes-fluent-client\";\nimport { startsWith } from \"ramda\";\n\nimport { Capability } from \"../core/capability\";\nimport { Store } from \"../k8s\";\nimport Log, { redactedPatch, redactedStore } from \"../telemetry/logger\";\nimport { DataOp, DataSender, DataStore, Storage } from \"../core/storage\";\nimport { fillStoreCache, sendUpdatesAndFlushCache } from \"./storeCache\";\nimport { migrateAndSetupWatch } from \"./migrateStore\";\n\nconst namespace = \"pepr-system\";\nconst debounceBackoffReceive = 1000;\nconst debounceBackoffSend = 4000;\n\nexport class StoreController {\n #name: string;\n #stores: Record<string, Storage> = {};\n #sendDebounce: NodeJS.Timeout | undefined;\n #onReady?: () => void;\n\n constructor(capabilities: Capability[], name: string, onReady?: () => void) {\n this.#onReady = onReady;\n\n this.#name = name;\n\n const setStorageInstance = (registrationFunction: () => Storage, name: string): void => {\n const scheduleStore = registrationFunction();\n\n // Bind the store sender to the capability\n scheduleStore.registerSender(this.#send(name));\n\n // Store the storage instance\n this.#stores[name] = scheduleStore;\n };\n\n if (name.includes(\"schedule\")) {\n // Establish the store for each capability\n for (const { name, registerScheduleStore, hasSchedule } of capabilities) {\n if (hasSchedule === true) {\n // Register the scheduleStore with the capability\n setStorageInstance(registerScheduleStore, name);\n }\n }\n } else {\n // Establish the store for each capability\n for (const { name, registerStore } of capabilities) {\n setStorageInstance(registerStore, name);\n }\n }\n\n setTimeout(\n () =>\n K8s(Store)\n .InNamespace(namespace)\n .Get(this.#name)\n .then(\n async (store: Store) =>\n await migrateAndSetupWatch({\n name,\n namespace,\n store,\n stores: this.#stores,\n setupWatch: this.#setupWatch,\n }),\n )\n .catch(this.#createStoreResource),\n Math.random() * 3000, // Add a jitter to the Store creation to avoid collisions\n );\n }\n\n #setupWatch = (): void => {\n const watcher = K8s(Store, { name: this.#name, namespace }).Watch(this.#receive);\n watcher.start().catch(e => Log.error(e, \"Error starting Pepr store watch\"));\n };\n\n #receive = (store: Store): void => {\n Log.debug(redactedStore(store), \"Pepr Store update\");\n\n // Wrap the update in a debounced function\n const debounced = (): void => {\n // Base64 decode the data\n const data: DataStore = store.data || {};\n\n // Loop over each stored capability\n for (const name of Object.keys(this.#stores)) {\n // Get the prefix offset for the keys\n const offset = `${name}-`.length;\n\n // Get any keys that match the capability name prefix\n const filtered: DataStore = {};\n\n // Loop over each key in the secret\n for (const key of Object.keys(data)) {\n // Match on the capability name as a prefix\n if (startsWith(name, key)) {\n // Strip the prefix and store the value\n filtered[key.slice(offset)] = data[key];\n }\n }\n\n // Send the data to the receiver callback\n this.#stores[name].receive(filtered);\n }\n\n // Call the onReady callback if this is the first time the secret has been read\n if (this.#onReady) {\n this.#onReady();\n this.#onReady = undefined;\n }\n };\n\n // Debounce the update to 1 second to avoid multiple rapid calls\n clearTimeout(this.#sendDebounce);\n this.#sendDebounce = setTimeout(debounced, this.#onReady ? 0 : debounceBackoffReceive);\n };\n\n #send = (capabilityName: string): DataSender => {\n let storeCache: Record<string, Operation> = {};\n\n // Create a sender function for the capability to add/remove data from the store\n const sender: DataSender = async (op: DataOp, key: string[], value?: string) => {\n storeCache = fillStoreCache(storeCache, capabilityName, op, { key, value });\n };\n\n // Send any cached updates every debounceBackoff milliseconds\n setInterval(() => {\n if (Object.keys(storeCache).length > 0) {\n Log.debug(redactedPatch(storeCache), \"Sending updates to Pepr store\");\n void sendUpdatesAndFlushCache(storeCache, namespace, this.#name);\n }\n }, debounceBackoffSend);\n\n return sender;\n };\n\n #createStoreResource = async (e: unknown): Promise<void> => {\n Log.debug(`Pepr store not found, creating...`);\n Log.debug(e);\n\n try {\n await K8s(Store).Apply({\n metadata: {\n name: this.#name,\n namespace,\n labels: {\n \"pepr.dev-cacheID\": `${Date.now()}`,\n },\n },\n data: {\n // JSON Patch will die if the data is empty, so we need to add a placeholder\n __pepr_do_not_delete__: \"k-thx-bye\",\n },\n });\n\n // Now that the resource exists, setup the watch\n this.#setupWatch();\n } catch (err) {\n Log.error(err, \"Failed to create Pepr store\");\n }\n };\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// SPDX-FileCopyrightText: 2023-Present The Pepr Authors\n\nimport { GenericKind, RegisterKind } from \"kubernetes-fluent-client\";\n\n/**\n * PeprStore for internal use by Pepr. This is used to store arbitrary data in the cluster.\n */\nexport class Store extends GenericKind {\n declare data: {\n [key: string]: string;\n };\n}\n\nexport const peprStoreGVK = {\n kind: \"PeprStore\",\n version: \"v1\",\n group: \"pepr.dev\",\n};\n\nRegisterKind(Store, peprStoreGVK);\n\nexport interface MutateResponse {\n /** UID is an identifier for the individual request/response. This must be copied over from the corresponding AdmissionRequest. */\n uid: string;\n\n /** Allowed indicates whether or not the admission request was permitted. */\n allowed: boolean;\n\n /** Result contains extra details into why an admission request was denied. This field IS NOT consulted in any way if \"Allowed\" is \"true\". */\n result?: string;\n\n /** The patch body. Currently we only support \"JSONPatch\" which implements RFC 6902. */\n patch?: string;\n\n /** The type of Patch. Currently we only allow \"JSONPatch\". */\n patchType?: \"JSONPatch\";\n\n /**\n * AuditAnnotations is an unstructured key value map set by remote admission controller (e.g. error=image-blacklisted).\n *\n * See https://kubernetes.io/docs/reference/labels-annotations-taints/audit-annotations/ for more information\n */\n auditAnnotations?: {\n [key: string]: string;\n };\n\n /** warnings is a list of warning messages to return to the requesting API client. */\n warnings?: string[];\n}\n\nexport interface ValidateResponse extends MutateResponse {\n /** Status contains extra details into why an admission request was denied. This field IS NOT consulted in any way if \"Allowed\" is \"true\". */\n status?: {\n /** A machine-readable description of why this operation is in the\n \"Failure\" status. If this value is empty there is no information available. */\n code: number;\n\n /** A human-readable description of the status of this operation. */\n message: string;\n };\n}\n\nexport type WebhookIgnore = {\n /**\n * List of Kubernetes namespaces to always ignore.\n * Any resources in these namespaces will be ignored by Pepr.\n *\n * Note: `kube-system` and `pepr-system` are always ignored.\n */\n namespaces?: string[];\n};\n", "import { DataOp } from \"../core/storage\";\nimport Log from \"../telemetry/logger\";\nimport { K8s } from \"kubernetes-fluent-client\";\nimport { Store } from \"../k8s\";\nimport { StatusCodes } from \"http-status-codes\";\nimport { Operation } from \"fast-json-patch\";\n\nexport const sendUpdatesAndFlushCache = async (\n cache: Record<string, Operation>,\n namespace: string,\n name: string,\n): Promise<Record<string, Operation>> => {\n const indexes = Object.keys(cache);\n const payload = Object.values(cache);\n\n try {\n if (payload.length > 0) {\n await K8s(Store, { namespace, name }).Patch(updateCacheID(payload)); // Send patch to cluster\n Object.keys(cache).forEach(key => delete cache[key]);\n }\n } catch (err) {\n Log.error(err, \"Pepr store update failure\");\n\n if (err.status === StatusCodes.UNPROCESSABLE_ENTITY) {\n Object.keys(cache).forEach(key => delete cache[key]);\n } else {\n indexes.forEach(index => {\n cache[index] = payload[Number(index)]; // On failure to update, re-add the operations to the cache to be retried\n });\n }\n }\n return cache;\n};\n\ntype CacheItem = {\n key: string[];\n value?: string;\n version?: string;\n};\n\nexport const fillStoreCache = (\n cache: Record<string, Operation>,\n capabilityName: string,\n op: DataOp,\n cacheItem: CacheItem,\n): Record<string, Operation> => {\n const path = [`/data/${capabilityName}`, cacheItem.version, cacheItem.key] // adjust the path, see ADR-0008\n .filter(str => str !== \"\" && str !== undefined)\n .join(\"-\");\n if (op === \"add\") {\n const value = cacheItem.value || \"\";\n const cacheIdx = [op, path, value].join(\":\");\n\n // Add the operation to the cache\n cache[cacheIdx] = { op, path, value };\n } else if (op === \"remove\") {\n if (cacheItem.key.length < 1) {\n throw new Error(`Key is required for REMOVE operation`);\n }\n const cacheIndex = [op, path].join(\":\");\n // Add the operation to the cache\n cache[cacheIndex] = { op, path };\n } else {\n throw new Error(`Unsupported operation: ${op}`);\n }\n return cache;\n};\n\nexport function updateCacheID(payload: Operation[]): Operation[] {\n payload.push({\n op: \"replace\",\n path: \"/metadata/labels/pepr.dev-cacheID\",\n value: `${Date.now()}`,\n });\n return payload;\n}\n", "import { DataStore, Storage } from \"../core/storage\";\nimport { startsWith } from \"ramda\";\nimport Log, { redactedStore } from \"../telemetry/logger\";\nimport { K8s } from \"kubernetes-fluent-client\";\nimport { Store } from \"../k8s\";\nimport { Operation } from \"fast-json-patch\";\nimport { fillStoreCache, sendUpdatesAndFlushCache } from \"./storeCache\";\n\nexport interface StoreMigration {\n name: string;\n namespace: string;\n store: Store;\n stores: Record<string, Storage>;\n setupWatch: () => void;\n}\n\nexport async function migrateAndSetupWatch(storeData: StoreMigration): Promise<void> {\n const { store, namespace, name, stores, setupWatch } = storeData;\n\n Log.debug(redactedStore(store), \"Pepr Store migration\");\n // Add cacheID label to store\n await K8s(Store, { namespace, name }).Patch([\n {\n op: \"add\",\n path: \"/metadata/labels/pepr.dev-cacheID\",\n value: `${Date.now()}`,\n },\n ]);\n\n const data: DataStore = store.data;\n let storeCache: Record<string, Operation> = {};\n\n for (const name of Object.keys(stores)) {\n // Get the prefix offset for the keys\n const offset = `${name}-`.length;\n\n // Loop over each key in the store\n for (const key of Object.keys(data)) {\n // Match on the capability name as a prefix for non v2 keys\n if (startsWith(name, key) && !startsWith(`${name}-v2`, key)) {\n // populate migrate cache\n storeCache = fillStoreCache(storeCache, name, \"remove\", {\n key: [key.slice(offset)],\n value: data[key],\n });\n storeCache = fillStoreCache(storeCache, name, \"add\", {\n key: [key.slice(offset)],\n value: data[key],\n version: \"v2\",\n });\n }\n }\n }\n storeCache = await sendUpdatesAndFlushCache(storeCache, namespace, name);\n setupWatch();\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// SPDX-FileCopyrightText: 2023-Present The Pepr Authors\n\nimport { AdmissionRequest } from \"../common-types\";\nimport { MutateResponse, ValidateResponse } from \"../k8s\";\nimport { ResponseItem } from \"../types\";\n\nexport interface KubeAdmissionReview {\n apiVersion: string;\n kind: string;\n response: ValidateResponse[] | MutateResponse | ResponseItem;\n}\n\nexport function karForMutate(mr: MutateResponse): KubeAdmissionReview {\n return {\n apiVersion: \"admission.k8s.io/v1\",\n kind: \"AdmissionReview\",\n response: mr,\n };\n}\n\nexport function karForValidate(ar: AdmissionRequest, vr: ValidateResponse[]): KubeAdmissionReview {\n const isAllowed = vr.filter(r => !r.allowed).length === 0;\n\n // Collect all warnings from the ValidateResponse array\n const warnings = vr.reduce<string[]>((acc, curr) => {\n if (curr.warnings && curr.warnings.length > 0) {\n return [...acc, ...curr.warnings];\n }\n return acc;\n }, []);\n\n const resp: ValidateResponse =\n vr.length === 0\n ? {\n uid: ar.uid,\n allowed: true,\n status: { code: 200, message: \"no in-scope validations -- allowed!\" },\n warnings: warnings.length > 0 ? warnings : undefined,\n }\n : {\n uid: vr[0].uid,\n allowed: isAllowed,\n status: {\n code: isAllowed ? 200 : 422,\n message: vr\n .filter(rl => !rl.allowed)\n .map(curr => curr.status?.message)\n .join(\"; \"),\n },\n warnings: warnings.length > 0 ? warnings : undefined,\n };\n return {\n apiVersion: \"admission.k8s.io/v1\",\n kind: \"AdmissionReview\",\n response: resp,\n };\n}\n", "export interface FeatureMetadata {\n name: string;\n description: string;\n defaultValue: FeatureValue;\n}\n\nexport interface FeatureInfo {\n key: string;\n metadata: FeatureMetadata;\n}\n// All known feature flags with their metadata\nexport const FeatureFlags: Record<string, FeatureInfo> = {\n REFERENCE_FLAG: {\n key: \"reference_flag\",\n metadata: {\n name: \"Reference Flag\",\n description: \"A feature flag to show intended usage.\",\n defaultValue: false,\n },\n },\n};\n\nexport type FeatureValue = string | boolean | number;\n", "// SPDX-License-Identifier: Apache-2.0\n// SPDX-FileCopyrightText: 2023-Present The Pepr Authors\n\nimport { FeatureFlags, FeatureValue } from \"./FeatureFlags\";\n\nexport class FeatureStore {\n private featureFlagLimit: number = 4;\n private features: Record<string, FeatureValue> = {};\n\n private addFeature(key: string, value: string): void {\n if (!key || value === undefined || value === \"\") return;\n\n const validKeys = Object.values(FeatureFlags)\n .filter(f => f?.key)\n .map(f => f.key);\n if (!validKeys.includes(key)) {\n throw new Error(`Unknown feature flag: ${key}`);\n }\n\n const lowerValue = value.toLowerCase();\n if (lowerValue === \"true\") {\n this.features[key] = true;\n } else if (lowerValue === \"false\") {\n this.features[key] = false;\n } else if (!isNaN(Number(value))) {\n this.features[key] = Number(value);\n } else {\n this.features[key] = value;\n }\n }\n\n get<T extends FeatureValue>(key: string): T {\n if (!Object.values(FeatureFlags).some(f => f?.key === key)) {\n throw new Error(`Unknown feature flag: ${key}`);\n }\n\n if (!(key in this.features)) {\n throw new Error(`Feature flag '${key}' exists but has not been set`);\n }\n\n return this.features[key] as T;\n }\n\n getAll(): Record<string, FeatureValue> {\n return { ...this.features };\n }\n\n initialize(featuresStr?: string, env: Record<string, string | undefined> = process.env): void {\n Object.keys(env)\n .filter(key => key.startsWith(\"PEPR_FEATURE_\"))\n .forEach(key => {\n this.addFeature(key.replace(\"PEPR_FEATURE_\", \"\").toLowerCase(), env[key] || \"\");\n });\n\n if (featuresStr) {\n featuresStr\n .split(\",\")\n .map(feature => feature.split(\"=\"))\n .filter(parts => parts.length === 2)\n .forEach(([key, value]) => {\n this.addFeature(key.trim(), value.trim());\n });\n }\n\n this.applyDefaultValues();\n this.validateFeatureCount();\n }\n\n private applyDefaultValues(): void {\n Object.values(FeatureFlags)\n .filter(\n feature =>\n feature?.key &&\n feature?.metadata?.defaultValue !== undefined &&\n !(feature.key in this.features),\n )\n .forEach(feature => {\n this.features[feature.key] = feature.metadata.defaultValue;\n });\n }\n\n validateFeatureCount(): void {\n const featureCount = Object.keys(this.features).length;\n if (featureCount > this.featureFlagLimit) {\n throw new Error(\n `Too many feature flags active: ${featureCount} (maximum: ${this.featureFlagLimit}). Use of more than ${this.featureFlagLimit} feature flags is not supported.`,\n );\n }\n }\n}\n\nexport const featureFlagStore = new FeatureStore();\n", "// SPDX-License-Identifier: Apache-2.0\n// SPDX-FileCopyrightText: 2023-Present The Pepr Authors\n\nimport { OnError } from \"../cli/init/enums\";\n\nexport const ErrorList = Object.values(OnError) as string[];\n/**\n * Validate the error or throw an error\n * @param error\n */\nexport function ValidateError(error: string = \"\"): void {\n if (!ErrorList.includes(error)) {\n throw new Error(`Invalid error: ${error}. Must be one of: ${ErrorList.join(\", \")}`);\n }\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// SPDX-FileCopyrightText: 2023-Present The Pepr Authors\nimport Log from \"../telemetry/logger\";\nimport { Binding } from \"../types\";\nimport { Capability } from \"../core/capability\";\nimport { Event } from \"../enums\";\nimport {\n K8s,\n KubernetesObject,\n WatchCfg,\n WatchEvent,\n GenericClass,\n} from \"kubernetes-fluent-client\";\nimport { Queue } from \"../core/queue\";\nimport { WatcherType } from \"kubernetes-fluent-client/dist/fluent/types\";\nimport { WatchPhase } from \"kubernetes-fluent-client/dist/fluent/shared-types\";\nimport { KubernetesListObject } from \"kubernetes-fluent-client/dist/types\";\nimport { filterNoMatchReason } from \"../filter/filter\";\nimport { metricsCollector, MetricsCollectorInstance } from \"../telemetry/metrics\";\nimport { removeFinalizer } from \"../finalizer\";\n\n// stores Queue instances\nconst queues: Record<string, Queue<KubernetesObject>> = {};\n\n/**\n * Get the key for an entry in the queues\n *\n * @param obj The object to derive a key from\n * @returns The key to a Queue in the list of queues\n */\nexport function queueKey(obj: KubernetesObject): string {\n const options = [\"kind\", \"kindNs\", \"kindNsName\", \"global\"];\n const d3fault = \"kindNsName\";\n\n let strat = process.env.PEPR_RECONCILE_STRATEGY || d3fault;\n strat = options.includes(strat) ? strat : d3fault;\n\n const ns = obj.metadata?.namespace ?? \"cluster-scoped\";\n const kind = obj.kind ?? \"UnknownKind\";\n const name = obj.metadata?.name ?? \"Unnamed\";\n\n const lookup: Record<string, string> = {\n kind: `${kind}`,\n kindNs: `${kind}/${ns}`,\n kindNsName: `${kind}/${ns}/${name}`,\n global: \"global\",\n };\n return lookup[strat];\n}\n\nexport function getOrCreateQueue(obj: KubernetesObject): Queue<KubernetesObject> {\n const key = queueKey(obj);\n if (!queues[key]) {\n queues[key] = new Queue<KubernetesObject>(key);\n }\n return queues[key];\n}\n\n// Watch configuration\nconst watchCfg: WatchCfg = {\n resyncFailureMax: process.env.PEPR_RESYNC_FAILURE_MAX\n ? parseInt(process.env.PEPR_RESYNC_FAILURE_MAX, 10)\n : 5,\n resyncDelaySec: process.env.PEPR_RESYNC_DELAY_SECONDS\n ? parseInt(process.env.PEPR_RESYNC_DELAY_SECONDS, 10)\n : 5,\n lastSeenLimitSeconds: process.env.PEPR_LAST_SEEN_LIMIT_SECONDS\n ? parseInt(process.env.PEPR_LAST_SEEN_LIMIT_SECONDS, 10)\n : 300,\n relistIntervalSec: process.env.PEPR_RELIST_INTERVAL_SECONDS\n ? parseInt(process.env.PEPR_RELIST_INTERVAL_SECONDS, 10)\n : 600,\n};\n\n// Map the event to the watch phase\nconst eventToPhaseMap = {\n [Event.CREATE]: [WatchPhase.Added],\n [Event.UPDATE]: [WatchPhase.Modified],\n [Event.CREATE_OR_UPDATE]: [WatchPhase.Added, WatchPhase.Modified],\n [Event.DELETE]: [WatchPhase.Deleted],\n [Event.ANY]: [WatchPhase.Added, WatchPhase.Modified, WatchPhase.Deleted],\n};\n\n/**\n * Entrypoint for setting up watches for all capabilities\n *\n * @param capabilities The capabilities to load watches for\n */\nexport function setupWatch(capabilities: Capability[], ignoredNamespaces?: string[]): void {\n for (const capability of capabilities) {\n for (const binding of capability.bindings.filter(b => b.isWatch)) {\n void runBinding(binding, capability.namespaces, ignoredNamespaces);\n }\n }\n}\n\n/**\n * Setup a watch for a binding\n *\n * @param binding the binding to watch\n * @param capabilityNamespaces list of namespaces to filter on\n */\nexport async function runBinding(\n binding: Binding,\n capabilityNamespaces: string[],\n ignoredNamespaces?: string[],\n): Promise<void> {\n // Get the phases to match, fallback to any\n const phaseMatch: WatchPhase[] = eventToPhaseMap[binding.event] || eventToPhaseMap[Event.ANY];\n\n // The watch callback is run when an object is received or dequeued\n Log.debug({ watchCfg }, \"Effective WatchConfig\");\n\n const watchCallback = async (\n kubernetesObject: KubernetesObject,\n phase: WatchPhase,\n ): Promise<void> => {\n // First, filter the object based on the phase\n if (phaseMatch.includes(phase)) {\n try {\n // Then, check if the object matches the filter\n const filterMatch = filterNoMatchReason(\n binding,\n kubernetesObject,\n capabilityNamespaces,\n ignoredNamespaces,\n );\n if (filterMatch !== \"\") {\n Log.debug(filterMatch);\n return;\n }\n if (binding.isFinalize) {\n await handleFinalizerRemoval(kubernetesObject);\n } else {\n await binding.watchCallback?.(kubernetesObject, phase);\n }\n } catch (e) {\n // Errors in the watch callback should not crash the controller\n Log.error(e, \"Error executing watch callback\");\n }\n }\n };\n\n const handleFinalizerRemoval = async (kubernetesObject: KubernetesObject): Promise<void> => {\n if (!kubernetesObject.metadata?.deletionTimestamp) {\n return;\n }\n let shouldRemoveFinalizer: boolean | void | undefined = true;\n try {\n shouldRemoveFinalizer = await binding.finalizeCallback?.(kubernetesObject);\n\n // if not opt'ed out of / if in error state, remove pepr finalizer\n } finally {\n const peprFinal = \"pepr.dev/finalizer\";\n const meta = kubernetesObject.metadata!;\n const resource = `${meta.namespace || \"ClusterScoped\"}/${meta.name}`;\n\n // [ true, void, undefined ] SHOULD remove finalizer\n // [ false ] should NOT remove finalizer\n if (shouldRemoveFinalizer === false) {\n Log.debug(\n { obj: kubernetesObject },\n `Skipping removal of finalizer '${peprFinal}' from '${resource}'`,\n );\n } else {\n await removeFinalizer(binding, kubernetesObject);\n }\n }\n };\n\n // Setup the resource watch\n const watcher = K8s(binding.model, { ...binding.filters, kindOverride: binding.kind }).Watch(\n async (obj, phase) => {\n Log.debug(obj, `Watch event ${phase} received`);\n\n if (binding.isQueue) {\n const queue = getOrCreateQueue(obj);\n await queue.enqueue(obj, phase, watchCallback);\n } else {\n await watchCallback(obj, phase);\n }\n },\n watchCfg,\n );\n\n // Register event handlers\n try {\n registerWatchEventHandlers(watcher, logEvent, metricsCollector);\n } catch (err) {\n throw new Error(\n \"WatchEventHandler Registration Error: Unable to register event watch handler.\",\n { cause: err },\n );\n }\n\n // Start the watch\n try {\n await watcher.start();\n } catch (err) {\n throw new Error(\"WatchStart Error: Unable to start watch.\", { cause: err });\n }\n}\n\nexport function logEvent(event: WatchEvent, message: string = \"\", obj?: KubernetesObject): void {\n const logMessage = `Watch event ${event} received${message ? `. ${message}.` : \".\"}`;\n if (obj) {\n Log.debug(obj, logMessage);\n } else {\n Log.debug(logMessage);\n }\n}\n\nexport type WatchEventArgs<K extends WatchEvent, T extends GenericClass> = {\n [WatchEvent.LIST]: KubernetesListObject<InstanceType<T>>;\n [WatchEvent.RECONNECT]: number;\n [WatchEvent.CACHE_MISS]: string;\n [WatchEvent.INIT_CACHE_MISS]: string;\n [WatchEvent.GIVE_UP]: Error;\n [WatchEvent.ABORT]: Error;\n [WatchEvent.OLD_RESOURCE_VERSION]: string;\n [WatchEvent.NETWORK_ERROR]: Error;\n [WatchEvent.LIST_ERROR]: Error;\n [WatchEvent.DATA_ERROR]: Error;\n [WatchEvent.CONNECT]: string;\n [WatchEvent.RECONNECT_PENDING]: undefined;\n [WatchEvent.DATA]: undefined;\n [WatchEvent.INC_RESYNC_FAILURE_COUNT]: number;\n}[K];\n\nexport type LogEventFunction = (event: WatchEvent, message?: string) => void;\nexport function registerWatchEventHandlers(\n watcher: WatcherType<GenericClass>,\n logEvent: LogEventFunction,\n metricsCollector: MetricsCollectorInstance,\n): void {\n const eventHandlers: {\n [K in WatchEvent]?: (arg: WatchEventArgs<K, GenericClass>) => void;\n } = {\n [WatchEvent.DATA]: () => null,\n [WatchEvent.GIVE_UP]: err => {\n // If failure continues, log and exit\n logEvent(WatchEvent.GIVE_UP, err.message);\n throw new Error(\n \"WatchEvent GiveUp Error: The watch has failed to start after several attempts.\",\n { cause: err },\n );\n },\n [WatchEvent.CONNECT]: url => logEvent(WatchEvent.CONNECT, url),\n [WatchEvent.DATA_ERROR]: err => logEvent(WatchEvent.DATA_ERROR, err.message),\n [WatchEvent.RECONNECT]: retryCount =>\n logEvent(\n WatchEvent.RECONNECT,\n `Reconnecting after ${retryCount} attempt${retryCount === 1 ? \"\" : \"s\"}`,\n ),\n [WatchEvent.RECONNECT_PENDING]: () => logEvent(WatchEvent.RECONNECT_PENDING),\n [WatchEvent.ABORT]: err => logEvent(WatchEvent.ABORT, err.message),\n [WatchEvent.OLD_RESOURCE_VERSION]: errMessage =>\n logEvent(WatchEvent.OLD_RESOURCE_VERSION, errMessage),\n [WatchEvent.NETWORK_ERROR]: err => logEvent(WatchEvent.NETWORK_ERROR, err.message),\n [WatchEvent.LIST_ERROR]: err => logEvent(WatchEvent.LIST_ERROR, err.message),\n [WatchEvent.LIST]: list => logEvent(WatchEvent.LIST, JSON.stringify(list, undefined, 2)),\n [WatchEvent.CACHE_MISS]: windowName => metricsCollector.incCacheMiss(windowName),\n [WatchEvent.INIT_CACHE_MISS]: windowName => metricsCollector.initCacheMissWindow(windowName),\n [WatchEvent.INC_RESYNC_FAILURE_COUNT]: retryCount => metricsCollector.incRetryCount(retryCount),\n };\n\n Object.entries(eventHandlers).forEach(([event, handler]) => {\n watcher.events.on(event, handler);\n });\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// SPDX-FileCopyrightText: 2023-Present The Pepr Authors\nimport { KubernetesObject } from \"@kubernetes/client-node\";\nimport { WatchPhase } from \"kubernetes-fluent-client/dist/fluent/shared-types\";\nimport { randomBytes } from \"node:crypto\";\nimport Log from \"../telemetry/logger\";\n\ntype WatchCallback = (obj: KubernetesObject, phase: WatchPhase) => Promise<void>;\n\ntype QueueItem<K extends KubernetesObject> = {\n item: K;\n phase: WatchPhase;\n callback: WatchCallback;\n resolve: (value: void | PromiseLike<void>) => void;\n reject: (reason?: string) => void;\n};\n\n/**\n * Queue is a FIFO queue for reconciling\n */\nexport class Queue<K extends KubernetesObject> {\n #name: string;\n #uid: string;\n #queue: QueueItem<K>[] = [];\n #pendingPromise = false;\n\n constructor(name: string) {\n this.#name = name;\n this.#uid = `${Date.now()}-${randomBytes(2).toString(\"hex\")}`;\n }\n\n label(): { name: string; uid: string } {\n return { name: this.#name, uid: this.#uid };\n }\n\n stats(): {\n queue: {\n name: string;\n uid: string;\n };\n stats: {\n length: number;\n };\n } {\n return {\n queue: this.label(),\n stats: {\n length: this.#queue.length,\n },\n };\n }\n\n /**\n * Enqueue adds an item to the queue and returns a promise that resolves when the item is\n * reconciled.\n *\n * @param item The object to reconcile\n * @param type The watch phase requested for reconcile\n * @param reconcile The callback to enqueue for reconcile\n * @returns A promise that resolves when the object is reconciled\n */\n enqueue(item: K, phase: WatchPhase, reconcile: WatchCallback): Promise<void> {\n const note = {\n queue: this.label(),\n item: {\n name: item.metadata?.name,\n namespace: item.metadata?.namespace,\n resourceVersion: item.metadata?.resourceVersion,\n },\n };\n Log.debug(note, \"Enqueueing\");\n return new Promise<void>((resolve, reject) => {\n this.#queue.push({ item, phase, callback: reconcile, resolve, reject });\n Log.debug(this.stats(), \"Queue stats - push\");\n return this.#dequeue();\n });\n }\n\n /**\n * Dequeue reconciles the next item in the queue\n *\n * @returns A promise that resolves when the webapp is reconciled\n */\n async #dequeue(): Promise<false | undefined> {\n // If there is a pending promise, do nothing\n if (this.#pendingPromise) {\n Log.debug(\"Pending promise, not dequeuing\");\n return false;\n }\n\n // Take the next element from the queue\n const element = this.#queue.shift();\n\n // If there is no element, do nothing\n if (!element) {\n Log.debug(\"No element, not dequeuing\");\n return false;\n }\n\n try {\n // Set the pending promise flag to avoid concurrent reconciliations\n this.#pendingPromise = true;\n\n // Reconcile the element\n const note = {\n queue: this.label(),\n item: {\n name: element.item.metadata?.name,\n namespace: element.item.metadata?.namespace,\n resourceVersion: element.item.metadata?.resourceVersion,\n },\n };\n Log.debug(note, \"Reconciling\");\n await element.callback(element.item, element.phase);\n Log.debug(note, \"Reconciled\");\n\n element.resolve();\n } catch (e) {\n Log.debug({ error: e }, `Error reconciling ${element.item.metadata!.name}`);\n element.reject(e);\n } finally {\n Log.debug(this.stats(), \"Queue stats - shift\");\n\n // Reset the pending promise flag\n Log.debug(\"Resetting pending promise and dequeuing\");\n this.#pendingPromise = false;\n\n // After the element is reconciled, dequeue the next element\n await this.#dequeue();\n }\n }\n}\n", "import { ControllerHooks } from \".\";\nimport { resolveIgnoreNamespaces } from \"../assets/ignoredNamespaces\";\nimport { Capability } from \"../core/capability\";\nimport { isWatchMode, isDevMode } from \"../core/envChecks\";\nimport { setupWatch } from \"../processors/watch-processor\";\nimport { PeprModuleOptions } from \"../types\";\n\n/**\n * Creates controller hooks with proper handling of watch setup\n *\n * @param opts Module options including hooks\n * @param capabilities List of capabilities\n * @param ignoreNamespaces Namespaces to ignore\n * @returns Controller hooks configuration\n */\nexport function createControllerHooks(\n opts: PeprModuleOptions,\n capabilities: Capability[],\n ignoreNamespaces: string[] = [],\n): ControllerHooks {\n return {\n beforeHook: opts.beforeHook,\n afterHook: opts.afterHook,\n onReady: async (): Promise<void> => {\n if (isWatchMode() || isDevMode()) {\n try {\n setupWatch(capabilities, resolveIgnoreNamespaces(ignoreNamespaces));\n } catch (error) {\n throw new Error(`WatchError: Could not set up watch.`, { cause: error });\n }\n }\n },\n };\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// SPDX-FileCopyrightText: 2023-Present The Pepr Authors\n\nimport { PeprValidateRequest } from \"../lib/validate-request\";\nimport { PeprMutateRequest } from \"../lib/mutate-request\";\nimport { V1OwnerReference, V1Container } from \"@kubernetes/client-node\";\nimport { GenericKind, K8s, kind } from \"kubernetes-fluent-client\";\n\n/**\n * Returns all containers in a pod\n * @param request the request/pod to get the containers from\n * @param containerType the type of container to get\n * @returns the list of containers in the pod\n */\nexport function containers(\n request: PeprValidateRequest<kind.Pod> | PeprMutateRequest<kind.Pod>,\n containerType?: \"containers\" | \"initContainers\" | \"ephemeralContainers\",\n): V1Container[] {\n const containers = request.Raw.spec?.containers || [];\n const initContainers = request.Raw.spec?.initContainers || [];\n const ephemeralContainers = request.Raw.spec?.ephemeralContainers || [];\n\n if (containerType === \"containers\") {\n return containers;\n }\n if (containerType === \"initContainers\") {\n return initContainers;\n }\n if (containerType === \"ephemeralContainers\") {\n return ephemeralContainers;\n }\n return [...containers, ...initContainers, ...ephemeralContainers];\n}\n\n/**\n * Write a K8s event for a CRD\n *\n * @param cr The custom resource to write the event for\n * @param event The event to write, should contain a human-readable message for the event\n * @param eventType The type of event to write, for example \"Warning\"\n * @param eventReason The reason for the event, for example \"ReconciliationFailed\"\n * @param reportingComponent The component that is reporting the event, for example \"uds.dev/operator\"\n * @param reportingInstance The instance of the component that is reporting the event, for example process.env.HOSTNAME\n */\n\nexport async function writeEvent(\n cr: GenericKind,\n event: Partial<kind.CoreEvent>,\n options: {\n eventType: string;\n eventReason: string;\n reportingComponent: string;\n reportingInstance: string;\n },\n): Promise<void> {\n const { eventType, eventReason, reportingComponent, reportingInstance } = options;\n\n await K8s(kind.CoreEvent).Create({\n type: eventType,\n reason: eventReason,\n ...event,\n // Fixed values\n metadata: {\n namespace: cr.metadata!.namespace,\n generateName: cr.metadata!.name,\n },\n involvedObject: {\n apiVersion: cr.apiVersion,\n kind: cr.kind,\n name: cr.metadata!.name,\n namespace: cr.metadata!.namespace,\n uid: cr.metadata!.uid,\n },\n firstTimestamp: new Date(),\n reportingComponent: reportingComponent,\n reportingInstance: reportingInstance,\n });\n}\n\n/**\n * Get the owner reference for a custom resource\n * @param customResource the custom resource to get the owner reference for\n * @param blockOwnerDeletion if true, AND if the owner has the \"foregroundDeletion\" finalizer, then the owner cannot be deleted from the key-value store until this reference is removed.\n * @param controller if true, this reference points to the managing controller.\n * @returns the owner reference array for the custom resource\n */\nexport function getOwnerRefFrom(\n customResource: GenericKind,\n blockOwnerDeletion?: boolean,\n controller?: boolean,\n): V1OwnerReference[] {\n const { apiVersion, kind, metadata } = customResource;\n const { name, uid } = metadata!;\n\n return [\n {\n apiVersion: apiVersion!,\n kind: kind!,\n uid: uid!,\n name: name!,\n ...(blockOwnerDeletion !== undefined && { blockOwnerDeletion }),\n ...(controller !== undefined && { controller }),\n },\n ];\n}\n\n/**\n * Sanitize a resource name to make it a valid Kubernetes resource name.\n *\n * @param name the name of the resource to sanitize\n * @returns the sanitized resource name\n *\n * https://kubernetes.io/docs/concepts/overview/working-with-objects/names/\n */\nexport function sanitizeResourceName(name: string): string {\n return (\n name\n .toLowerCase()\n // Replace invalid characters (anything not a-z, 0-9, or '-') with '-'\n .replace(/[^a-z0-9-]+/g, \"-\")\n // Trim to 63 characters (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#rfc-1035-label-names)\n .slice(0, 63)\n // Remove leading non-alphanumeric characters\n .replace(/^[^a-z0-9]+/, \"\")\n // Remove trailing non-alphanumeric characters\n .replace(/[^a-z0-9]+$/, \"\")\n );\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["a", "import_kubernetes_fluent_client", "import_kubernetes_fluent_client", "import_ramda", "pointer", "pointer", "kind", "kind", "import_ramda", "promClient", "import_ramda", "import_ramda", "import_ramda", "import_ramda", "import_ramda", "kind", "uncarryableNamespace", "missingCarriableNamespace", "carriesIgnoredNamespace", "uncarryableNamespace", "carriesIgnoredNamespace", "missingCarriableNamespace", "import_ramda", "OnError", "import_ramda", "jsonPatch", "import_ramda", "processRequest", "import_kubernetes_fluent_client", "import_ramda", "import_kubernetes_fluent_client", "import_kubernetes_fluent_client", "namespace", "import_ramda", "import_kubernetes_fluent_client", "namespace", "setupWatch", "name", "name", "express", "fs", "https", "namespace", "res", "import_kubernetes_fluent_client", "kind", "logEvent", "metricsCollector", "import_kubernetes_fluent_client", "containers", "kind"]
|
|
7
7
|
}
|