Skip to content

Commit

Permalink
Merge pull request #135 from ajuste/update-s3
Browse files Browse the repository at this point in the history
chore: update aws-sdk to v3 and accept s3 region
  • Loading branch information
drodil authored Mar 26, 2024
2 parents 834c784 + 40450ca commit 40e0c1e
Show file tree
Hide file tree
Showing 7 changed files with 1,197 additions and 38 deletions.
1 change: 1 addition & 0 deletions docs/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,4 @@ The configuration values are:
- storage.bucket, string, bucket ARN for S3 storage, required for S3 storage
- storage.accessKeyId, string, access key ID for S3 storage, optional
- storage.secretAccessKey, string, secret access key for S3 storage, optional
- storage.region, string, region for S3 storage, optional
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@
},
"packageManager": "[email protected]",
"dependencies": {
"@octokit/rest": "19.0.8",
"aws-sdk": "^2.1583.0"
"@aws-sdk/client-s3": "^3.540.0",
"@octokit/rest": "19.0.8"
}
}
1 change: 1 addition & 0 deletions plugins/qeta-backend/configSchema.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ export interface Config {
bucket?: string;
accessKeyId?: string;
secretAccessKey?: string;
region?: string;
};
};
}
1 change: 1 addition & 0 deletions plugins/qeta-backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"tsc": "tsc"
},
"dependencies": {
"@aws-sdk/client-s3": "^3.540.0",
"@backstage/backend-common": "^0.21.4",
"@backstage/backend-plugin-api": "^0.6.14",
"@backstage/catalog-model": "^1.4.5",
Expand Down
30 changes: 20 additions & 10 deletions plugins/qeta-backend/src/service/routes/attachments.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@ import S3StoreEngine from '../upload/s3';
import fs from 'fs';
import FileType from 'file-type';
import { File } from '../types';
import { S3 } from 'aws-sdk';
import {
S3Client,
GetObjectCommand,
GetObjectCommandOutput,
} from '@aws-sdk/client-s3';

const DEFAULT_IMAGE_SIZE_LIMIT = 2500000;
const DEFAULT_MIME_TYPES = [
Expand Down Expand Up @@ -101,7 +105,7 @@ export const attachmentsRoutes = (router: Router, options: RouterOptions) => {
return response.status(404).send('Attachment not found');
}

let imageBuffer: Buffer;
let imageBuffer: Buffer | undefined;
if (attachment.locationType === 'database') {
imageBuffer = attachment.binaryImage;
} else if (attachment.locationType === 's3') {
Expand All @@ -110,25 +114,31 @@ export const attachmentsRoutes = (router: Router, options: RouterOptions) => {
const secretAccessKey = config.getOptionalString(
'qeta.storage.secretAccessKey',
);
const region = config.getOptionalString('qeta.storage.region');
if (!bucket) {
throw new Error('Bucket name is required for S3 storage');
}
const s3 =
accessKeyId && secretAccessKey
? new S3({
accessKeyId && secretAccessKey && region
? new S3Client({
credentials: {
accessKeyId,
secretAccessKey,
},
region,
})
: new S3();
const object = await s3
.getObject({
: new S3Client();
const object: GetObjectCommandOutput = await s3.send(
new GetObjectCommand({
Bucket: bucket,
Key: attachment.path,
})
.promise();
imageBuffer = object.Body as Buffer;
}),
);

if (object.Body) {
const bytes = await object.Body.transformToByteArray();
imageBuffer = Buffer.from(bytes);
}
} else {
imageBuffer = await fs.promises.readFile(attachment.path);
}
Expand Down
16 changes: 9 additions & 7 deletions plugins/qeta-backend/src/service/upload/s3.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Config } from '@backstage/config';
import { QetaStore } from '../../database/QetaStore';
import { Attachment } from '@drodil/backstage-plugin-qeta-common';
import { File } from '../types';
import { S3 } from 'aws-sdk';
import { S3Client, PutObjectCommand } from '@aws-sdk/client-s3';

type Options = {
config: Config;
Expand All @@ -21,6 +21,7 @@ class S3StoreEngine {
bucket?: string;
accessKeyId?: string;
secretAccessKey?: string;
region?: string;

constructor(opts: Options) {
this.config = opts.config;
Expand All @@ -37,19 +38,20 @@ class S3StoreEngine {
this.folder =
this.config.getOptionalString('qeta.storage.folder') ||
'/backstage-qeta-images';
this.region = this.config.getOptionalString('qeta.storage.region');
}

newClient = (): S3 => {
if (this.accessKeyId && this.secretAccessKey) {
return new S3({
newClient = (): S3Client => {
if (this.accessKeyId && this.secretAccessKey && this.region) {
return new S3Client({
credentials: {
accessKeyId: this.accessKeyId,
secretAccessKey: this.secretAccessKey,
},
region: this.region,
});
}

return new S3();
return new S3Client({});
};

handleFile = async (file: File): Promise<Attachment> => {
Expand All @@ -67,7 +69,7 @@ class S3StoreEngine {
Body: fs.createReadStream(file.path),
};

await client.upload(uploadArgs).promise();
await client.send(new PutObjectCommand(uploadArgs));

const attachment = await this.database.postAttachment({
uuid: imageUuid,
Expand Down
Loading

0 comments on commit 40e0c1e

Please sign in to comment.