From e84229ad355b60935dc077bb23f1c91f0fa212ec Mon Sep 17 00:00:00 2001 From: Rob Ferguson Date: Fri, 12 Jul 2024 00:02:10 -0500 Subject: [PATCH] chore: add util function for purging orphans (#565) ## Description Uses common function for purging orphan resources ## Type of change - [ ] Bug fix (non-breaking change which fixes an issue) - [ ] New feature (non-breaking change which adds functionality) - [x] Other (security config, docs update, etc) ## Checklist before merging - [ ] Test, docs, adr added or updated as needed - [ ] [Contributor Guide](https://github.com/defenseunicorns/uds-template-capability/blob/main/CONTRIBUTING.md) followed --- .../controllers/istio/istio-resources.ts | 37 ++----------------- .../authservice/authorization-policy.ts | 14 +------ .../controllers/monitoring/pod-monitor.ts | 19 +--------- .../controllers/monitoring/service-monitor.ts | 19 +--------- .../operator/controllers/network/policies.ts | 19 +--------- src/pepr/operator/controllers/utils.ts | 21 ++++++++++- 6 files changed, 31 insertions(+), 98 deletions(-) diff --git a/src/pepr/operator/controllers/istio/istio-resources.ts b/src/pepr/operator/controllers/istio/istio-resources.ts index 63e2ca95b..297aec6b0 100644 --- a/src/pepr/operator/controllers/istio/istio-resources.ts +++ b/src/pepr/operator/controllers/istio/istio-resources.ts @@ -2,7 +2,7 @@ import { K8s } from "pepr"; import { Component, setupLogger } from "../../../logger"; import { IstioServiceEntry, IstioVirtualService, UDSPackage } from "../../crd"; -import { getOwnerRef } from "../utils"; +import { getOwnerRef, purgeOrphans } from "../utils"; import { generateServiceEntry } from "./service-entry"; import { generateVirtualService } from "./virtual-service"; @@ -57,39 +57,8 @@ export async function istioResources(pkg: UDSPackage, namespace: string) { serviceEntryNames.set(sePayload.metadata!.name!, true); } - // Get all related VirtualServices in the namespace - const virtualServices = await K8s(IstioVirtualService) - .InNamespace(namespace) - .WithLabel("uds/package", pkgName) - .Get(); - - // Find any orphaned VirtualServices (not matching the current generation) - const orphanedVS = virtualServices.items.filter( - vs => vs.metadata?.labels?.["uds/generation"] !== generation, - ); - - // Delete any orphaned VirtualServices - for (const vs of orphanedVS) { - log.debug(vs, `Deleting orphaned VirtualService ${vs.metadata!.name}`); - await K8s(IstioVirtualService).Delete(vs); - } - - // Get all related ServiceEntries in the namespace - const serviceEntries = await K8s(IstioServiceEntry) - .InNamespace(namespace) - .WithLabel("uds/package", pkgName) - .Get(); - - // Find any orphaned ServiceEntries (not matching the current generation) - const orphanedSE = serviceEntries.items.filter( - se => se.metadata?.labels?.["uds/generation"] !== generation, - ); - - // Delete any orphaned ServiceEntries - for (const se of orphanedSE) { - log.debug(se, `Deleting orphaned ServiceEntry ${se.metadata!.name}`); - await K8s(IstioServiceEntry).Delete(se); - } + await purgeOrphans(generation, namespace, pkgName, IstioVirtualService, log); + await purgeOrphans(generation, namespace, pkgName, IstioServiceEntry, log); // Return the list of unique hostnames return [...hosts]; diff --git a/src/pepr/operator/controllers/keycloak/authservice/authorization-policy.ts b/src/pepr/operator/controllers/keycloak/authservice/authorization-policy.ts index 0966495c8..8e48c7629 100644 --- a/src/pepr/operator/controllers/keycloak/authservice/authorization-policy.ts +++ b/src/pepr/operator/controllers/keycloak/authservice/authorization-policy.ts @@ -6,7 +6,7 @@ import { IstioRequestAuthentication, UDSPackage, } from "../../../crd"; -import { getOwnerRef } from "../../utils"; +import { getOwnerRef, purgeOrphans } from "../../utils"; import { log } from "./authservice"; import { Action as AuthServiceAction, AuthServiceEvent } from "./types"; @@ -155,17 +155,7 @@ async function updatePolicy( async function purgeOrphanPolicies(generation: string, namespace: string, pkgName: string) { for (const kind of [IstioAuthorizationPolicy, IstioRequestAuthentication]) { - const resources = await K8s(kind) - .InNamespace(namespace) - .WithLabel("uds/package", pkgName) - .Get(); - - for (const resource of resources.items) { - if (resource.metadata?.labels?.["uds/generation"] !== generation) { - log.debug(resource, `Deleting orphaned ${resource.kind!} ${resource.metadata!.name}`); - await K8s(kind).Delete(resource); - } - } + await purgeOrphans(generation, namespace, pkgName, kind, log); } } diff --git a/src/pepr/operator/controllers/monitoring/pod-monitor.ts b/src/pepr/operator/controllers/monitoring/pod-monitor.ts index 2ac1c2e11..655015562 100644 --- a/src/pepr/operator/controllers/monitoring/pod-monitor.ts +++ b/src/pepr/operator/controllers/monitoring/pod-monitor.ts @@ -3,7 +3,7 @@ import { K8s } from "pepr"; import { Component, setupLogger } from "../../../logger"; import { Monitor, PrometheusPodMonitor, UDSPackage } from "../../crd"; import { Kind } from "../../crd/generated/package-v1alpha1"; -import { getOwnerRef } from "../utils"; +import { getOwnerRef, purgeOrphans } from "../utils"; import { generateMonitorName } from "./common"; // configure subproject logger @@ -42,22 +42,7 @@ export async function podMonitor(pkg: UDSPackage, namespace: string) { } } - // Get all related PodMonitors in the namespace - const podMonitors = await K8s(PrometheusPodMonitor) - .InNamespace(namespace) - .WithLabel("uds/package", pkgName) - .Get(); - - // Find any orphaned PodMonitors (not matching the current generation) - const orphanedMonitor = podMonitors.items.filter( - m => m.metadata?.labels?.["uds/generation"] !== generation, - ); - - // Delete any orphaned PodMonitors - for (const m of orphanedMonitor) { - log.debug(m, `Deleting orphaned PodMonitor ${m.metadata!.name}`); - await K8s(PrometheusPodMonitor).Delete(m); - } + await purgeOrphans(generation, namespace, pkgName, PrometheusPodMonitor, log); } catch (err) { throw new Error(`Failed to process PodMonitors for ${pkgName}, cause: ${JSON.stringify(err)}`); } diff --git a/src/pepr/operator/controllers/monitoring/service-monitor.ts b/src/pepr/operator/controllers/monitoring/service-monitor.ts index 641c9e86c..9f567c245 100644 --- a/src/pepr/operator/controllers/monitoring/service-monitor.ts +++ b/src/pepr/operator/controllers/monitoring/service-monitor.ts @@ -4,7 +4,7 @@ import { V1OwnerReference } from "@kubernetes/client-node"; import { Component, setupLogger } from "../../../logger"; import { Monitor, PrometheusServiceMonitor, UDSPackage } from "../../crd"; import { Kind } from "../../crd/generated/package-v1alpha1"; -import { getOwnerRef } from "../utils"; +import { getOwnerRef, purgeOrphans } from "../utils"; import { generateMonitorName } from "./common"; // configure subproject logger @@ -43,22 +43,7 @@ export async function serviceMonitor(pkg: UDSPackage, namespace: string) { } } - // Get all related ServiceMonitors in the namespace - const serviceMonitors = await K8s(PrometheusServiceMonitor) - .InNamespace(namespace) - .WithLabel("uds/package", pkgName) - .Get(); - - // Find any orphaned ServiceMonitors (not matching the current generation) - const orphanedMonitor = serviceMonitors.items.filter( - m => m.metadata?.labels?.["uds/generation"] !== generation, - ); - - // Delete any orphaned ServiceMonitors - for (const m of orphanedMonitor) { - log.debug(m, `Deleting orphaned ServiceMonitor ${m.metadata!.name}`); - await K8s(PrometheusServiceMonitor).Delete(m); - } + await purgeOrphans(generation, namespace, pkgName, PrometheusServiceMonitor, log); } catch (err) { throw new Error( `Failed to process ServiceMonitors for ${pkgName}, cause: ${JSON.stringify(err)}`, diff --git a/src/pepr/operator/controllers/network/policies.ts b/src/pepr/operator/controllers/network/policies.ts index 2f7e13daa..4cb341fa1 100644 --- a/src/pepr/operator/controllers/network/policies.ts +++ b/src/pepr/operator/controllers/network/policies.ts @@ -2,7 +2,7 @@ import { K8s, kind } from "pepr"; import { Component, setupLogger } from "../../../logger"; import { Allow, Direction, Gateway, UDSPackage } from "../../crd"; -import { getOwnerRef, sanitizeResourceName } from "../utils"; +import { getOwnerRef, purgeOrphans, sanitizeResourceName } from "../utils"; import { allowEgressDNS } from "./defaults/allow-egress-dns"; import { allowEgressIstiod } from "./defaults/allow-egress-istiod"; import { allowIngressSidecarMonitoring } from "./defaults/allow-ingress-sidecar-monitoring"; @@ -146,22 +146,7 @@ export async function networkPolicies(pkg: UDSPackage, namespace: string) { await K8s(kind.NetworkPolicy).Apply(policy, { force: true }); } - // Delete any policies that are no longer needed - const policyList = await K8s(kind.NetworkPolicy) - .InNamespace(namespace) - .WithLabel("uds/package", pkgName) - .Get(); - - // Find any orphaned polices (not matching the current generation) - const orphanedNetPol = policyList.items.filter( - netPol => netPol.metadata?.labels?.["uds/generation"] !== generation, - ); - - // Delete any orphaned policies - for (const netPol of orphanedNetPol) { - log.debug(netPol, `Deleting orphaned NetworkPolicy ${netPol.metadata!.name}`); - await K8s(kind.NetworkPolicy).Delete(netPol); - } + await purgeOrphans(generation, namespace, pkgName, kind.NetworkPolicy, log); // Return the list of policies return policies; diff --git a/src/pepr/operator/controllers/utils.ts b/src/pepr/operator/controllers/utils.ts index b6a8df198..b9c6d0ca3 100644 --- a/src/pepr/operator/controllers/utils.ts +++ b/src/pepr/operator/controllers/utils.ts @@ -1,5 +1,7 @@ import { V1OwnerReference } from "@kubernetes/client-node"; -import { GenericKind } from "kubernetes-fluent-client"; +import { GenericClass, GenericKind } from "kubernetes-fluent-client"; +import { K8s } from "pepr"; +import { Logger } from "pino"; /** * Sanitize a resource name to make it a valid Kubernetes resource name. @@ -38,3 +40,20 @@ export function getOwnerRef(cr: GenericKind): V1OwnerReference[] { }, ]; } + +export async function purgeOrphans( + generation: string, + namespace: string, + pkgName: string, + kind: T, + log: Logger, +) { + const resources = await K8s(kind).InNamespace(namespace).WithLabel("uds/package", pkgName).Get(); + + for (const resource of resources.items) { + if (resource.metadata?.labels?.["uds/generation"] !== generation) { + log.debug(resource, `Deleting orphaned ${resource.kind!} ${resource.metadata!.name}`); + await K8s(kind).Delete(resource); + } + } +}