mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-09 04:50:59 +00:00
fix(offhost): judge the bucket's rules for database/ against this instance's folder
The dumps now live under database/<host of APP_URL>/, so the rule check reads a sample key in that folder: a rule scoped to this instance's folder counts, one scoped to another instance's does not.
This commit is contained in:
1 parent
a7691223fd
commit
2b79c01952
2 files changed
+36
-5
No files matched your search
@@ -3,7 +3,7 @@
|
||||
* from the account copies: a rule scoped to another prefix, or to a tag, does
|
||||
* not touch them.
|
||||
*/
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import type { LifecycleRule } from "@aws-sdk/client-s3";
|
||||
|
||||
import { lifecycleFromRules, ruleAppliesTo } from "../offhost-lifecycle";
|
||||
@@ -29,6 +29,25 @@ describe("lifecycle rules and the database dumps", () => {
|
||||
).toEqual({ state: "configured", expirationDays: 14 });
|
||||
});
|
||||
|
||||
it("reads the rules for this instance's own folder under database/", () => {
|
||||
vi.stubEnv("APP_URL", "https://health.example.org");
|
||||
try {
|
||||
expect(
|
||||
lifecycleFromRules([
|
||||
rule(30, { Filter: { Prefix: "2026-" } }),
|
||||
rule(9, { Filter: { Prefix: "database/health.example.org/" } }),
|
||||
]).database,
|
||||
).toEqual({ state: "configured", expirationDays: 9 });
|
||||
expect(
|
||||
lifecycleFromRules([
|
||||
rule(9, { Filter: { Prefix: "database/staging.example.org/" } }),
|
||||
]).database,
|
||||
).toEqual({ state: "missing", expirationDays: null });
|
||||
} finally {
|
||||
vi.unstubAllEnvs();
|
||||
}
|
||||
});
|
||||
|
||||
it("says database/ is not covered when the only rule is scoped elsewhere", () => {
|
||||
const result = lifecycleFromRules([
|
||||
rule(30, { Filter: { Prefix: "2026-" } }),
|
||||
|
||||
@@ -16,6 +16,10 @@
|
||||
* without `s3:GetLifecycleConfiguration`, a target that does not implement the
|
||||
* call, a network failure) and says nothing either way.
|
||||
*/
|
||||
import {
|
||||
instanceIdFromEnv,
|
||||
offhostObjectKey,
|
||||
} from "@/lib/database-backup/dump-core.mjs";
|
||||
import type { LifecycleRule } from "@aws-sdk/client-s3";
|
||||
|
||||
export interface LifecycleVerdict {
|
||||
@@ -40,9 +44,17 @@ export const LIFECYCLE_MISSING: OffhostLifecycle = {
|
||||
database: { state: "missing", expirationDays: null },
|
||||
};
|
||||
|
||||
/** A key a database dump is stored under, to test the rules against. */
|
||||
const DATABASE_SAMPLE_KEY =
|
||||
"database/healthlog-20260101T013000Z-daily.dump.enc";
|
||||
/**
|
||||
* A key this instance's database dumps are stored under, to test the rules
|
||||
* against: inside its own folder (`database/<host of APP_URL>/`), so a rule
|
||||
* scoped to that folder counts and one scoped to another instance's does not.
|
||||
*/
|
||||
function databaseSampleKey(): string {
|
||||
return offhostObjectKey(
|
||||
"healthlog-20260101T013000Z-daily.dump.enc",
|
||||
instanceIdFromEnv(),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether a rule's filter takes in `key`. Our objects carry no tags, so a
|
||||
@@ -73,7 +85,7 @@ export function lifecycleFromRules(
|
||||
return {
|
||||
...verdict(rules),
|
||||
database: verdict(
|
||||
rules.filter((rule) => ruleAppliesTo(rule, DATABASE_SAMPLE_KEY)),
|
||||
rules.filter((rule) => ruleAppliesTo(rule, databaseSampleKey())),
|
||||
),
|
||||
};
|
||||
}
|
||||
Reference in new issue
Block a user