diff --git a/packages/techdocs-common/__mocks__/aws-sdk.ts b/packages/techdocs-common/__mocks__/aws-sdk.ts new file mode 100644 index 0000000000..55cc953b82 --- /dev/null +++ b/packages/techdocs-common/__mocks__/aws-sdk.ts @@ -0,0 +1,65 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import type { S3 as S3Types } from 'aws-sdk'; +import { EventEmitter } from 'events'; +import fs from 'fs'; + +export class S3 { + private readonly options; + + constructor(options: S3Types.ClientConfiguration) { + this.options = options; + } + + headObject({ Key }: { Key: string }) { + return { + promise: this.promise, + createReadStream: () => { + const emitter = new EventEmitter(); + process.nextTick(() => { + emitter.emit('data', Buffer.from(fs.readFileSync(Key))); + emitter.emit('end'); + }); + return emitter; + }, + }; + } + + getObject({ Key }: { Key: string }) { + return { + promise: () => + new Promise(resolve => { + resolve(fs.existsSync(Key)); + }), + }; + } + + promise() { + return new Promise(resolve => { + resolve(''); + }); + } + + upload() { + return { + promise: this.promise, + }; + } +} + +export default { + S3, +}; diff --git a/packages/techdocs-common/package.json b/packages/techdocs-common/package.json index 7fc88a5238..9b945cc677 100644 --- a/packages/techdocs-common/package.json +++ b/packages/techdocs-common/package.json @@ -43,6 +43,7 @@ "@google-cloud/storage": "^5.6.0", "@types/dockerode": "^3.2.1", "@types/express": "^4.17.6", + "aws-sdk": "^2.813.0", "cross-fetch": "^3.0.6", "dockerode": "^3.2.1", "express": "^4.17.1", diff --git a/packages/techdocs-common/src/stages/publish/publish.test.ts b/packages/techdocs-common/src/stages/publish/publish.test.ts index c61b9aa3ec..b3fe98cce6 100644 --- a/packages/techdocs-common/src/stages/publish/publish.test.ts +++ b/packages/techdocs-common/src/stages/publish/publish.test.ts @@ -21,6 +21,7 @@ import { ConfigReader } from '@backstage/config'; import { Publisher } from './publish'; import { LocalPublish } from './local'; import { GoogleGCSPublish } from './googleStorage'; +import { AwsS3Publish } from './awsS3'; const logger = getVoidLogger(); const discovery: jest.Mocked = { @@ -81,4 +82,22 @@ describe('Publisher', () => { }); expect(publisher).toBeInstanceOf(GoogleGCSPublish); }); + + it('should create AWS S3 publisher from config', () => { + const mockConfig = new ConfigReader({ + techdocs: { + requestUrl: 'http://localhost:7000', + publisher: { + type: 'awsS3', + awsS3: { + credentials: '{}', + bucketName: 'bucketName', + }, + }, + }, + }); + + const publisher = Publisher.fromConfig(mockConfig, logger, testDiscovery); + expect(publisher).toBeInstanceOf(AwsS3Publish); + }); }); diff --git a/packages/techdocs-common/src/stages/publish/publish.ts b/packages/techdocs-common/src/stages/publish/publish.ts index 95b5cf83e2..caaf8a4cec 100644 --- a/packages/techdocs-common/src/stages/publish/publish.ts +++ b/packages/techdocs-common/src/stages/publish/publish.ts @@ -20,6 +20,7 @@ import { PluginEndpointDiscovery } from '@backstage/backend-common'; import { PublisherType, PublisherBase } from './types'; import { LocalPublish } from './local'; import { GoogleGCSPublish } from './googleStorage'; +import { AwsS3Publish } from './awsS3'; type factoryOptions = { logger: Logger; @@ -43,6 +44,9 @@ export class Publisher { case 'googleGcs': logger.info('Creating Google Storage Bucket publisher for TechDocs'); return GoogleGCSPublish.fromConfig(config, logger); + case 'awsS3': + logger.info('Creating AWS S3 Bucket publisher for TechDocs'); + return AwsS3Publish.fromConfig(config, logger); case 'local': logger.info('Creating Local publisher for TechDocs'); return new LocalPublish(config, logger, discovery); diff --git a/packages/techdocs-common/src/stages/publish/types.ts b/packages/techdocs-common/src/stages/publish/types.ts index 9bfd8cb334..24a9d05adf 100644 --- a/packages/techdocs-common/src/stages/publish/types.ts +++ b/packages/techdocs-common/src/stages/publish/types.ts @@ -19,7 +19,7 @@ import express from 'express'; /** * Key for all the different types of TechDocs publishers that are supported. */ -export type PublisherType = 'local' | 'googleGcs'; +export type PublisherType = 'local' | 'googleGcs' | 'awsS3'; export type PublishRequest = { entity: Entity;