From e65bf621bac42f07f4a8af5c296f13584b779f60 Mon Sep 17 00:00:00 2001 From: f1ames Date: Thu, 28 Sep 2023 16:32:44 +0200 Subject: [PATCH] refactor: draft ValidatorManager class --- admission-webhook/src/index.ts | 56 ++----------------- .../src/utils/validation-server.ts | 14 ++--- .../src/utils/validator-manager.ts | 25 +++++++++ 3 files changed, 38 insertions(+), 57 deletions(-) create mode 100644 admission-webhook/src/utils/validator-manager.ts diff --git a/admission-webhook/src/index.ts b/admission-webhook/src/index.ts index 68cb5c3..ff49e3d 100644 --- a/admission-webhook/src/index.ts +++ b/admission-webhook/src/index.ts @@ -1,7 +1,8 @@ import pino from 'pino'; -import {AnnotationSuppressor, FingerprintSuppressor, MonokleValidator, RemotePluginLoader, SchemaLoader, DisabledFixer, ResourceParser} from '@monokle/validation'; import {getInformer} from './utils/get-informer.js'; import {MonoklePolicy, MonoklePolicyBinding, PolicyManager} from './utils/policy-manager.js'; +import {ValidatorManager} from './utils/validator-manager.js'; +import {ValidationServer} from './utils/validation-server.js'; const logger = pino({ name: 'Monokle', @@ -28,56 +29,11 @@ const logger = pino({ ); const policyManager = new PolicyManager(policyInformer, bindingsInformer, logger); + const validatorManager = new ValidatorManager(policyManager); - // POLICY MANAGER + await policyManager.start(); - // // INFORMER - // const onPolicy = async (policy: MonoklePolicy) => { - // logger.info({msg: 'Informer: Policy updated', policy}); + const server = new ValidationServer(validatorManager, logger); - // const policyNamespace = policy.metadata?.namespace; - // if (!policyNamespace) { - // logger.error({msg: 'Informer: Policy namespace is empty', metadata: policy.metadata}); - // return; - // } - - // policies.set(policyNamespace, policy.spec); - - // if (!validators.has(policyNamespace)) { - // validators.set( - // policyNamespace, - // new MonokleValidator( - // { - // loader: new RemotePluginLoader(), - // parser: new ResourceParser(), - // schemaLoader: new SchemaLoader(), - // suppressors: [new AnnotationSuppressor(), new FingerprintSuppressor()], - // fixer: new DisabledFixer(), - // }, - // {} - // ) - // ); - // } - - // await validators.get(policyNamespace)!.preload(policy.spec); - // } - - // const onPolicyRemoval = async (policy: MonoklePolicy) => { - // logger.info('Informer: Policy removed'); - - // const policyNamespace = policy.metadata?.namespace; - // if (!policyNamespace) { - // logger.error({msg: 'Informer: Policy namespace is empty', metadata: policy.metadata}); - // return; - // } - - // policies.delete(policyNamespace); - // validators.delete(policyNamespace); - // } - - - // // SERVER - // const server = new ValidationServer(validators, logger); - - // await server.start(); + await server.start(); })(); diff --git a/admission-webhook/src/utils/validation-server.ts b/admission-webhook/src/utils/validation-server.ts index cdab3b1..2763ec2 100644 --- a/admission-webhook/src/utils/validation-server.ts +++ b/admission-webhook/src/utils/validation-server.ts @@ -2,8 +2,9 @@ import fastify from "fastify"; import pino from 'pino'; import path from "path"; import {readFileSync} from "fs"; -import {MonokleValidator, Resource} from "@monokle/validation"; +import {Resource} from "@monokle/validation"; import {V1ValidatingWebhookConfiguration, V1ObjectMeta} from "@kubernetes/client-node"; +import {ValidatorManager} from "./validator-manager"; export type ValidationServerOptions = { port: number; @@ -33,7 +34,7 @@ export class ValidationServer { private _shouldValidate: boolean constructor( - private readonly _validators: Map, + private readonly _validators: ValidatorManager, private readonly _logger: ReturnType, private readonly _options: ValidationServerOptions = { port: 8443, @@ -113,10 +114,8 @@ export class ValidationServer { return response; } - const validator = this._validators.get(namespace); - if (!validator) { - this._logger.info({msg: 'No validator found for namespace', namespace}); - + const validators = this._validators.getMatchingValidators(); + if (validators.length === 0) { return response; } @@ -129,7 +128,8 @@ export class ValidationServer { } const resourceForValidation = this._createResourceForValidation(body); - const validationResponse = await validator.validate({ resources: [resourceForValidation] }); + // @TODO iterate over validators and run them all + const validationResponse = await validators[0].validate({ resources: [resourceForValidation] }); const warnings = []; const errors = []; diff --git a/admission-webhook/src/utils/validator-manager.ts b/admission-webhook/src/utils/validator-manager.ts new file mode 100644 index 0000000..28d7590 --- /dev/null +++ b/admission-webhook/src/utils/validator-manager.ts @@ -0,0 +1,25 @@ +import {MonokleValidator} from "@monokle/validation"; +import {PolicyManager} from "./policy-manager"; + +export class ValidatorManager { + private _validators = new Map(); // Map + + constructor( + private readonly _policyManager: PolicyManager, + ) { + // @TODO implement this._policyManager.on(policyUpdated, this._reloadValidator) + // We should preload configuration here instead of in getMatchingValidators since + // it would affect performance of the admission webhook response time + } + + getMatchingValidators(): MonokleValidator[] { + const matchingPolicies = this._policyManager.getMatchingPolicies(); + + if (matchingPolicies.length === 0) { + return []; + } + + // @TODO + return []; + } +} \ No newline at end of file