Files
MikrotikManager/backend/scripts/acceptance/s3-owned-versions-cleanup.mjs
T

5 lines
2.6 KiB
JavaScript

import assert from 'node:assert/strict';import fs from 'node:fs';import{createRequire}from'node:module';import{createS3ClientFromConfig}from'/app/backend/dist/services/s3-backup-client.js';const require=createRequire('/app/backend/package.json'),{ListObjectVersionsCommand,DeleteObjectCommand}=require('@aws-sdk/client-s3');const bucket=process.env.MMAPP_TEST_S3_BUCKET;assert.equal(bucket,'mikrotik-test-s3');const client=createS3ClientFromConfig({endpoint:process.env.MMAPP_TEST_S3_ENDPOINT,region:process.env.MMAPP_TEST_S3_REGION,bucket,prefix:'mmapp-acceptance',accessKeyId:process.env.MMAPP_TEST_S3_ACCESS_KEY,secretAccessKey:process.env.MMAPP_TEST_S3_SECRET_KEY,forcePathStyle:false});const reports=JSON.parse(fs.readFileSync('/checks/owned-prefixes-public.json'));const plans=[],out={at:new Date().toISOString(),bucketConfigurationWrites:0,prefixes:[],passed:false};
async function list(prefix){let keyMarker,versionMarker,rows=[];for(let page=0;page<50;page++){const r=await client.send(new ListObjectVersionsCommand({Bucket:bucket,Prefix:prefix+'/',KeyMarker:keyMarker,VersionIdMarker:versionMarker}));rows.push(...(r.Versions??[]).map(v=>({...v,kind:'version'})),...(r.DeleteMarkers??[]).map(v=>({...v,kind:'delete-marker'})));if(!r.IsTruncated)return rows;assert(r.NextKeyMarker||r.NextVersionIdMarker);keyMarker=r.NextKeyMarker;versionMarker=r.NextVersionIdMarker;}throw Error('Version pagination limit')}
function isOwn(r,key){if(r.plannedKeys)return r.plannedKeys.includes(key);const relative=key.slice(r.prefix.length+1);return relative==='seed/probe-sync.rsc'||/^(s3-(?:positive|only)-[a-f0-9-]{36})\/\1_\d{4}-\d{2}-\d{2}_\d{2}-\d{2}-\d{2}\.rsc$/.test(relative)}
try{for(const r of reports){assert(/^mmapp-acceptance\/[a-f0-9-]{36}$/.test(r.prefix));const rows=await list(r.prefix);for(const row of rows)assert(row.Key?.startsWith(r.prefix+'/')&&isOwn(r,row.Key)&&typeof row.VersionId==='string'&&row.VersionId.length>0,'Unexpected version: do not delete');plans.push({r,rows});}for(const{r,rows}of plans){let removed=0;for(const row of rows){await client.send(new DeleteObjectCommand({Bucket:bucket,Key:row.Key,VersionId:row.VersionId}));removed++;}const after=await list(r.prefix);assert.equal(after.length,0);out.prefixes.push({prefix:r.prefix,versionsBefore:rows.filter(r=>r.kind==='version').length,deleteMarkersBefore:rows.filter(r=>r.kind==='delete-marker').length,removed,versionsAndMarkersRemaining:0});}out.passed=true}catch(e){out.failure={name:e.name,httpStatus:e.$metadata?.httpStatusCode??null}}finally{client.destroy();fs.writeFileSync('/checks/owned-versions-cleanup-public.json',JSON.stringify(out,null,2)+'\n');console.log(JSON.stringify(out));if(!out.passed)process.exitCode=1}