all repos — s3brm @ c543e4f5a809b6216e18a72f1b34faed6c7c6ca6

S3 Backup Retention Manager

mod.ts (view raw)

 1import { S3, S3Object } from "https://deno.land/x/s3@0.5.0/mod.ts";
 2import { terminal } from "https://raw.githubusercontent.com/5ika/ink/master/mod.ts";
 3import { getStartOfMonth, getStartOfWeek, isSameDate } from "./date.ts";
 4
 5const debugMode = Deno.args.includes("--debug") || Deno.args.includes("-d");
 6
 7if (debugMode)
 8  terminal.log("<yellow>DEBUG MODE - Nothing will be deleted</yellow>");
 9
10const s3 = new S3({
11  accessKeyID: Deno.env.get("S3_ACCESS_KEY")!,
12  secretKey: Deno.env.get("S3_SECRET_KEY")!,
13  region: Deno.env.get("S3_REGION")!,
14  endpointURL: Deno.env.get("S3_ENDPOINT_URL"),
15});
16
17const bucket = s3.getBucket(Deno.env.get("S3_BUCKET")!);
18const items: AsyncGenerator<S3Object> = bucket.listAllObjects({
19  prefix: Deno.env.get("FILES_PREFIX") ?? "",
20  batchSize: 1000,
21});
22
23const today: Date = new Date();
24const dailyBackupInterval = Deno.env.get("DAILY_BACKUP_INTERVAL") || 13;
25const dailyBackupMaxDate: Date = new Date(
26  new Date().setDate(today.getDate() - parseInt(`${dailyBackupInterval}`))
27);
28const weeklyBackupInterval = Deno.env.get("WEEKLY_BACKUP_INTERVAL") || 31;
29const weeklyBackupMaxDate: Date = new Date(
30  new Date().setDate(today.getDate() - parseInt(`${weeklyBackupInterval}`))
31);
32const monthlyBackupInterval = Deno.env.get("MONTHLY_BACKUP_INTERVAL") || 183;
33const monthlyBackupMaxDate: Date = new Date(
34  new Date().setDate(today.getDate() - parseInt(`${monthlyBackupInterval}`))
35);
36
37for await (const item of items) {
38  // If item is a directory or has no date
39  if (item.size === 0 || !item?.lastModified || !item.key) continue;
40
41  // Keep items wich is first day of month and has date < monthlyBackupInterval days ago
42  const startOfMonth = getStartOfMonth(item.lastModified);
43  if (
44    item.lastModified > monthlyBackupMaxDate &&
45    isSameDate(item.lastModified, startOfMonth)
46  ) {
47    terminal.log(
48      `<magenta>Keep ${item.key} [monthly backup, < ${monthlyBackupInterval} days]</magenta>`
49    );
50    continue;
51  }
52
53  // Keep items wich is first day of week and has date < 1 weeklyBackupInterval days ago
54  const startOfWeek = getStartOfWeek(item.lastModified);
55  if (
56    item.lastModified > weeklyBackupMaxDate &&
57    isSameDate(item.lastModified, startOfWeek)
58  ) {
59    terminal.log(
60      `<cyan>Keep ${item.key} [weekly backup, < ${weeklyBackupInterval} days]</cyan>`
61    );
62    continue;
63  }
64
65  // Keep items with date < dailyBackupInterval days ago
66  if (item.lastModified > dailyBackupMaxDate) {
67    terminal.log(
68      `<dim>Keep ${item.key} [daily backup, < ${dailyBackupInterval} days]</dim>`
69    );
70    continue;
71  }
72
73  // Delete others
74  terminal.log(`<red>Delete ${item.key}</red>`);
75  if (!debugMode)
76    try {
77      await bucket.deleteObject(item.key);
78    } catch (error) {
79      terminal.log(item.key, error);
80    }
81}