support for s3 and minio

This commit is contained in:
2021-11-18 19:16:44 +01:00
parent 63e801ad05
commit c05ee888eb
10 changed files with 604 additions and 21 deletions

View File

@@ -1,30 +1,63 @@
import { FastifyInstance } from 'fastify'
import { Config, StorageType } from '../config'
import { Local } from './local'
import { Minio } from './minio'
export abstract class Storage {
abstract init(): Promise<void>
abstract read(path: string): Promise<Buffer>
abstract write(path: string, data: Buffer): Promise<void>
abstract exists(path: string): Promise<boolean>
abstract delete(path: string): Promise<void>
abstract readStream(path: string): Promise<NodeJS.ReadableStream>
abstract writeStream(path: string): Promise<NodeJS.WritableStream>
// list(path: string): Promise<string[]>
abstract init(): Promise<void>
// list(path: string): Promise<string[]>
abstract exists(path: string): Promise<boolean>
abstract delete(path: string): Promise<void>
}
export let storage: Storage
export async function init() {
export async function init(App: FastifyInstance) {
if (!storage) {
switch (Config.storage) {
case StorageType.Local:
storage = new Local(Config.localAssets)
break
case StorageType.S3:
// storage = new S3({
// accessKeyId: Config.s3.accessKey,
// secretAccessKey: Config.s3.secretKey,
// bucket: Config.s3.bucket,
// region: Config.s3.region,
// })
storage = new Minio({
accessKey: Config.s3.accessKey,
secretKey: Config.s3.secretKey,
bucket: Config.s3.bucket,
region: Config.s3.region,
endpoint: 'https://s3.amazonaws.com',
})
break
case StorageType.Minio:
storage = new Minio({
accessKey: Config.minio.accessKey,
secretKey: Config.minio.secretKey,
endpoint: Config.minio.endpoint,
region: Config.minio.region,
bucket: Config.minio.bucket,
})
break
default:
throw new Error(`Unknown storage type: ${Config.storage}`)
}
await storage.init()
try {
await storage.init()
App.log.debug(`Storage initialized: ${Config.storage}`)
} catch (e) {
App.log.error(`Storage initialization failed: ${Config.storage}`)
process.exit(1)
}
}
}

64
src/storage/minio.ts Normal file
View File

@@ -0,0 +1,64 @@
import { Client } from 'minio'
import { PassThrough } from 'stream'
import { Storage } from '.'
import { StreamUtils } from '../utils/utils'
export type MinioConfig = {
accessKey: string
secretKey: string
endpoint: string
region?: string
bucket: string
}
export class Minio implements Storage {
client: Client
constructor(private options: MinioConfig) {
const url = new URL(this.options.endpoint)
this.client = new Client({
accessKey: options.accessKey,
secretKey: options.secretKey,
endPoint: url.hostname,
port: parseInt(url.port),
useSSL: url.protocol === 'https:',
})
}
async init(): Promise<void> {
await this.client.bucketExists(this.options.bucket)
}
async read(path: string): Promise<Buffer> {
const stream = await this.client.getObject(this.options.bucket, path)
return StreamUtils.toBuffer(stream)
}
async write(path: string, data: Buffer): Promise<void> {
const stream = await StreamUtils.fromBuffer(data)
await this.client.putObject(this.options.bucket, path, stream)
}
async readStream(path: string): Promise<NodeJS.ReadableStream> {
const stream = await this.client.getObject(this.options.bucket, path)
return stream
}
async writeStream(path: string): Promise<NodeJS.WritableStream> {
const stream = new PassThrough()
this.client.putObject(this.options.bucket, path, stream)
return stream
}
async exists(path: string): Promise<boolean> {
try {
await this.client.statObject(this.options.bucket, path)
return true
} catch {
return false
}
}
delete(path: string): Promise<void> {
throw new Error('Method not implemented. Delete')
}
}