csa-backend-test/app/services/minio.services.js

159 lines
4.2 KiB
JavaScript

// ENVIRONMENTS
require('dotenv').config();
// SERVICES
const logger = require("../services/logger.services.js");
// CONSTANTS
const { MINIO_ENDPOINT, MINIO_ACCESS_KEY, MINIO_SECRET_KEY } = process.env;
const Minio = require("minio");
const minioClient = new Minio.Client({
endPoint: MINIO_ENDPOINT,
port: 443,
useSSL: true,
accessKey: MINIO_ACCESS_KEY,
secretKey: MINIO_SECRET_KEY,
});
/**
* Create a new bucket and set default public policy
*/
async function createBucket(bucketName) {
return new Promise((resolve, reject) => {
minioClient.makeBucket(bucketName, "", function (err) {
if (err) return reject(err);
logger.info(`Bucket "${bucketName}" created successfully`);
const policy = {
Version: "2012-10-17",
Statement: [
{
Effect: "Allow",
Principal: { AWS: "*" },
Action: ["s3:GetObject"],
Resource: [`arn:aws:s3:::${bucketName}/*`],
},
],
};
minioClient.setBucketPolicy(bucketName, JSON.stringify(policy), (err) => {
if (err) return reject(err);
logger.info(`Public policy applied to bucket "${bucketName}"`);
resolve();
});
});
});
}
/**
* Delete an existing bucket (must be empty)
*/
async function deleteBucket(bucketName) {
return new Promise((resolve, reject) => {
minioClient.removeBucket(bucketName, function (err) {
if (err) return reject(err);
logger.info(`Bucket "${bucketName}" deleted successfully`);
resolve();
});
});
}
/**
* Rename a bucket (create new, copy objects, delete old)
*/
async function renameBucket(oldBucket, newBucket) {
try {
await createBucket(newBucket);
const objects = [];
const stream = minioClient.listObjects(oldBucket, "", true);
await new Promise((resolve, reject) => {
stream.on("data", obj => objects.push(obj));
stream.on("end", resolve);
stream.on("error", reject);
});
for (const obj of objects) {
await new Promise((resolve, reject) => {
minioClient.copyObject(
newBucket,
obj.name,
`/${oldBucket}/${obj.name}`,
function (err, etag) {
if (err) return reject(err);
logger.info(`Copied ${obj.name} to ${newBucket}`);
resolve(etag);
}
);
});
}
if (objects.length > 0) {
await minioClient.removeObjects(
oldBucket,
objects.map(o => o.name)
);
}
await deleteBucket(oldBucket);
logger.info(`Bucket renamed from "${oldBucket}" to "${newBucket}"`);
} catch (err) {
throw err;
}
}
/**
* Get all buckets
*/
async function getAllBuckets() {
return new Promise((resolve, reject) => {
minioClient.listBuckets((err, buckets) => {
if (err) return reject(err);
resolve(buckets);
});
});
}
/**
* Set bucket policy (public / private)
*/
async function setBucketPolicy(bucketName, policyType) {
let policy = "";
if (policyType === "public") {
policy = {
Version: "2012-10-17",
Statement: [
{
Effect: "Allow",
Principal: { AWS: ["*"] },
Action: ["s3:GetObject"],
Resource: [`arn:aws:s3:::${bucketName}/*`]
}
]
};
} else if (policyType === "private") {
policy = {
Version: "2012-10-17",
Statement: []
};
} else {
throw new Error("Invalid policy type, use 'public' or 'private'");
}
await minioClient.setBucketPolicy(bucketName, JSON.stringify(policy));
}
module.exports = {
minioClient,
createBucket,
deleteBucket,
renameBucket,
getAllBuckets,
setBucketPolicy
};