Skip to content

Commit

Permalink
fix: Check if removed from entire system (#226)
Browse files Browse the repository at this point in the history
  • Loading branch information
adityachoudhari26 authored Nov 22, 2024
1 parent c4f2532 commit 586c68f
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 5 deletions.
59 changes: 55 additions & 4 deletions packages/job-dispatch/src/resource/dispatch-resource.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,20 @@
import type { Tx } from "@ctrlplane/db";
import type { ResourceCondition } from "@ctrlplane/validators/resources";
import { isPresent } from "ts-is-present";

import { and, desc, eq, inArray, takeFirstOrNull } from "@ctrlplane/db";
import {
and,
desc,
eq,
inArray,
isNotNull,
takeFirstOrNull,
} from "@ctrlplane/db";
import { db } from "@ctrlplane/db/client";
import * as SCHEMA from "@ctrlplane/db/schema";
import { logger } from "@ctrlplane/logger";
import { ComparisonOperator } from "@ctrlplane/validators/conditions";
import { ResourceFilterType } from "@ctrlplane/validators/resources";

import { handleEvent } from "../events/index.js";
import { dispatchReleaseJobTriggers } from "../job-dispatch.js";
Expand Down Expand Up @@ -142,17 +153,46 @@ const getEnvironmentDeployments = (db: Tx, envId: string) =>
.where(eq(SCHEMA.environment.id, envId))
.then((rows) => rows.map((r) => r.deployment));

/**
* Gets the not in system filter for a system
* @param systemId - System ID to get the not in system filter for
* @returns Promise resolving to the not in system filter or null if not found
*/
const getNotInSystemFilter = async (
systemId: string,
): Promise<ResourceCondition | null> => {
const hasFilter = isNotNull(SCHEMA.environment.resourceFilter);
const system = await db.query.system.findFirst({
where: eq(SCHEMA.system.id, systemId),
with: { environments: { where: hasFilter } },
});
if (system == null) return null;

const filters = system.environments
.map((e) => e.resourceFilter)
.filter(isPresent);
if (filters.length === 0) return null;

return {
type: ResourceFilterType.Comparison,
operator: ComparisonOperator.Or,
not: true,
conditions: filters,
};
};

/**
* Dispatches hook events for resources that were removed from an environment
* @param db - Database transaction
* @param resourceIds - IDs of the resources that were removed
* @param envId - ID of the environment the resources were removed from
* @param env - Environment the resources were removed from
*/
export const dispatchEventsForRemovedResources = async (
db: Tx,
resourceIds: string[],
envId: string,
env: { id: string; systemId: string },
): Promise<void> => {
const { id: envId, systemId } = env;
log.info("Dispatching events for removed resources", { resourceIds, envId });

const deployments = await getEnvironmentDeployments(db, envId);
Expand All @@ -161,8 +201,19 @@ export const dispatchEventsForRemovedResources = async (
return;
}

const notInSystemFilter = await getNotInSystemFilter(systemId);
if (notInSystemFilter == null) {
log.warn("No system found for environment", { envId });
return;
}

const matchesResources = inArray(SCHEMA.resource.id, resourceIds);
const isRemovedFromSystem = SCHEMA.resourceMatchesMetadata(
db,
notInSystemFilter,
);
const resources = await db.query.resource.findMany({
where: inArray(SCHEMA.resource.id, resourceIds),
where: and(matchesResources, isRemovedFromSystem),
});

log.debug("Creating removal events", {
Expand Down
2 changes: 1 addition & 1 deletion packages/job-dispatch/src/resource/upsert.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ export const upsertResources = async (
envId: env.id,
count: removedIds.length,
});
await dispatchEventsForRemovedResources(tx, removedIds, env.id);
await dispatchEventsForRemovedResources(tx, removedIds, env);
}
}
}
Expand Down
1 change: 1 addition & 0 deletions packages/job-dispatch/src/resource/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ export const getEnvironmentsByResourceWithIdentifiers = (
.select({
id: schema.environment.id,
resourceFilter: schema.environment.resourceFilter,
systemId: schema.environment.systemId,
})
.from(schema.environment)
.innerJoin(schema.system, eq(schema.environment.systemId, schema.system.id))
Expand Down

0 comments on commit 586c68f

Please sign in to comment.