From 1640afc41d9d57c878934a1bdbdc765433994592 Mon Sep 17 00:00:00 2001 From: "Jens W. Klein" Date: Tue, 18 Jun 2024 09:50:32 +0200 Subject: [PATCH] add PDB --- src/backend-deployment.ts | 22 +++++++-- src/backend-pdb.ts | 59 +++++++++++++++++++++++++ test/__snapshots__/backend.test.ts.snap | 16 +++++++ 3 files changed, 94 insertions(+), 3 deletions(-) create mode 100644 src/backend-pdb.ts diff --git a/src/backend-deployment.ts b/src/backend-deployment.ts index b853917..234271f 100644 --- a/src/backend-deployment.ts +++ b/src/backend-deployment.ts @@ -1,6 +1,7 @@ import { Names } from 'cdk8s'; // eslint-disable-next-line import/no-extraneous-dependencies import { Construct } from 'constructs'; +import { PloneBackendPDB, PloneBackendPDBOptions } from './backend-pdb'; import * as k8s from './imports/k8s'; export interface PloneBackendDeploymentOptions { @@ -27,6 +28,13 @@ export interface PloneBackendDeploymentOptions { * @default - none */ readonly labels?: { [name: string]: string }; + + /** + * Create a PodDisruptionBugdet for the deployment? + * If given + * @default - none + */ + readonly pdbOptions?: PloneBackendPDBOptions; } export class PloneBackendDeployment extends Construct { @@ -40,8 +48,8 @@ export class PloneBackendDeployment extends Construct { ...options.labels ?? {}, ...label, }; - - const deploymentOpts: k8s.KubeDeploymentProps = { + const pdb = options.pdbOptions ?? true; + const deploymentOptions: k8s.KubeDeploymentProps = { metadata: { labels: options.labels ?? {}, }, @@ -64,6 +72,14 @@ export class PloneBackendDeployment extends Construct { }, }; - new k8s.KubeDeployment(this, 'deployment', deploymentOpts); + new k8s.KubeDeployment(this, 'deployment', deploymentOptions); + + if (pdb ?? false) { + const pdbOptions = { + ...options.pdbOptions ?? {}, + selector_label: { app: Names.toLabelValue(this) }, + }; + new PloneBackendPDB(this, 'pdb', pdbOptions); + } } } diff --git a/src/backend-pdb.ts b/src/backend-pdb.ts new file mode 100644 index 0000000..5345042 --- /dev/null +++ b/src/backend-pdb.ts @@ -0,0 +1,59 @@ +// eslint-disable-next-line import/no-extraneous-dependencies +import { Construct } from 'constructs'; +import { IntOrString, KubePodDisruptionBudget } from './imports/k8s'; + +export interface PloneBackendPDBOptions { + /** + * maxUnavailable specification + * @default - none + */ + readonly maxUnavailable?: number | string; + + /** + * minAvailable specification. + * @default 1 + */ + readonly minAvailable?: number | string; + + /** + * Selector label. + */ + readonly selector_label: { [name: string]: string }; + + /** + * Extra labels to associate with resources. + * @default - none + */ + readonly labels?: { [name: string]: string }; +} + +export class PloneBackendPDB extends Construct { + + constructor(scope: Construct, id: string, options: PloneBackendPDBOptions) { + super(scope, id); + + var maxUnavailable: IntOrString = IntOrString.fromString(''); // default value + if (typeof maxUnavailable === 'number') { + maxUnavailable = IntOrString.fromNumber(options.maxUnavailable as number); + } else if (typeof maxUnavailable === 'string') { + maxUnavailable = IntOrString.fromString(options.maxUnavailable as string); + } + var minAvailable: IntOrString = IntOrString.fromString(''); // default value + if (typeof minAvailable === 'number') { + minAvailable = IntOrString.fromNumber(options.minAvailable as number); + } else if (typeof minAvailable === 'string') { + minAvailable = IntOrString.fromString(options.minAvailable as string); + } + + new KubePodDisruptionBudget(this, 'PDB', { + metadata: { + labels: options.labels ?? {}, + }, + spec: { + selector: { matchLabels: options.selector_label }, + maxUnavailable: maxUnavailable, + minAvailable: minAvailable, + }, + }); + } +} diff --git a/test/__snapshots__/backend.test.ts.snap b/test/__snapshots__/backend.test.ts.snap index 77dfb8b..dc50cfd 100644 --- a/test/__snapshots__/backend.test.ts.snap +++ b/test/__snapshots__/backend.test.ts.snap @@ -32,6 +32,22 @@ exports[`defaults 1`] = ` }, }, }, + { + "apiVersion": "policy/v1", + "kind": "PodDisruptionBudget", + "metadata": { + "name": "plone-backend-deployment-pdb-c84dc10f", + }, + "spec": { + "maxUnavailable": "", + "minAvailable": "", + "selector": { + "matchLabels": { + "app": "plone-backend-deployment-c83d26f8", + }, + }, + }, + }, { "apiVersion": "v1", "kind": "Service",