diff --git a/docs/features/techdocs/configuration.md b/docs/features/techdocs/configuration.md index eac6799317..b3cb349778 100644 --- a/docs/features/techdocs/configuration.md +++ b/docs/features/techdocs/configuration.md @@ -61,7 +61,8 @@ techdocs: googleGcs: # An API key is required to write to a storage bucket. - pathToKey: '/path/to/google_application_credentials.json', + credentials: + $file: '/path/to/google_application_credentials.json', # Your GCP Project ID where the Cloud Storage Bucket is hosted. projectId: 'gcp-project-id' diff --git a/docs/features/techdocs/using-cloud-storage.md b/docs/features/techdocs/using-cloud-storage.md index 12e3acd1bf..55352b6c00 100644 --- a/docs/features/techdocs/using-cloud-storage.md +++ b/docs/features/techdocs/using-cloud-storage.md @@ -58,7 +58,7 @@ IAM & Admin console), and create a new key. Use JSON format for the key. A `.json` file will be downloaded. This is the secret key TechDocs will use to make API calls. Make it available in your Backstage server and/or your local development server and set it in the app config -`techdocs.publisher.googleGcs.pathToKey`. +`techdocs.publisher.googleGcs.credentials`. ```yaml techdocs: @@ -66,7 +66,8 @@ techdocs: type: 'googleGcs' googleGcs: projectId: 'gcp-project-id' - pathToKey: '/path/to/google_application_credentials.json' + credentials: + $file: '/path/to/google_application_credentials.json' ``` **4. GCS Bucket** @@ -83,7 +84,8 @@ techdocs: type: 'googleGcs' googleGcs: projectId: 'gcp-project-id' - pathToKey: '/path/to/google_application_credentials.json' + credentials: + $file: '/path/to/google_application_credentials.json' bucketName: 'name-of-techdocs-storage-bucket' ``` diff --git a/packages/techdocs-common/README.md b/packages/techdocs-common/README.md index 2940df2524..e4889d6f79 100644 --- a/packages/techdocs-common/README.md +++ b/packages/techdocs-common/README.md @@ -1,6 +1,6 @@ # @backstage/techdocs-common -Common functionalities for TechDocs, to be shared between techdocs plugins and techdocs-cli +Common functionalities for TechDocs, to be shared between techdocs-backend plugin and techdocs-cli This package is used by `techdocs-backend` to serve docs from different types of publishers (Google GCS, Local, etc.). It is also used to build docs and publish them to storage, by both `techdocs-backend` and `techdocs-cli`. diff --git a/packages/techdocs-common/package.json b/packages/techdocs-common/package.json index eb917edc2b..1bec23c17e 100644 --- a/packages/techdocs-common/package.json +++ b/packages/techdocs-common/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/techdocs-common", - "description": "Common functionalities for TechDocs, to be shared between techdocs plugins and techdocs-cli", + "description": "Common functionalities for TechDocs, to be shared between techdocs-backend plugin and techdocs-cli", "version": "0.1.1", "main": "src/index.ts", "types": "src/index.ts", diff --git a/packages/techdocs-common/src/stages/publish/googleStorage.test.ts b/packages/techdocs-common/src/stages/publish/googleStorage.test.ts index fa7bddc648..a61dcc2767 100644 --- a/packages/techdocs-common/src/stages/publish/googleStorage.test.ts +++ b/packages/techdocs-common/src/stages/publish/googleStorage.test.ts @@ -38,10 +38,6 @@ jest.spyOn(logger, 'info').mockReturnValue(logger); let publisher: PublisherBase; beforeEach(() => { - mockFs({ - '/path/to/google-application-credentials.json': '{}', - }); - const mockConfig = ConfigReader.fromConfigs([ { context: '', @@ -51,7 +47,7 @@ beforeEach(() => { publisher: { type: 'googleGcs', googleGcs: { - pathToKey: '/path/to/google-application-credentials.json', + credentials: '{}', projectId: 'gcp-project-id', bucketName: 'bucketName', }, @@ -64,10 +60,6 @@ beforeEach(() => { publisher = GoogleGCSPublish.fromConfig(mockConfig, logger); }); -afterEach(() => { - mockFs.restore(); -}); - describe('GoogleGCSPublish', () => { it('should publish a directory', () => { mockFs({ diff --git a/packages/techdocs-common/src/stages/publish/googleStorage.ts b/packages/techdocs-common/src/stages/publish/googleStorage.ts index c9b4ffd3db..d6868c1103 100644 --- a/packages/techdocs-common/src/stages/publish/googleStorage.ts +++ b/packages/techdocs-common/src/stages/publish/googleStorage.ts @@ -25,24 +25,35 @@ import { PublisherBase, PublishRequest } from './types'; export class GoogleGCSPublish implements PublisherBase { static fromConfig(config: Config, logger: Logger): PublisherBase { - let pathToKey = ''; + let credentials = ''; let projectId = ''; let bucketName = ''; try { - pathToKey = config.getString('techdocs.publisher.googleGcs.pathToKey'); + credentials = config.getString( + 'techdocs.publisher.googleGcs.credentials', + ); projectId = config.getString('techdocs.publisher.googleGcs.projectId'); bucketName = config.getString('techdocs.publisher.googleGcs.bucketName'); } catch (error) { throw new Error( "Since techdocs.publisher.type is set to 'googleGcs' in your app config, " + - 'pathToKey, projectId and bucketName are required in techdocs.publisher.googleGcs ' + + 'credentials, projectId and bucketName are required in techdocs.publisher.googleGcs ' + 'required to authenticate with Google Cloud Storage.', ); } + let credentialsJson = {}; + try { + credentialsJson = JSON.parse(credentials); + } catch (err) { + throw new Error( + 'Error in parsing techdocs.publisher.googleGcs.credentials config to JSON.', + ); + } + const storageClient = new Storage({ + credentials: credentialsJson, projectId: projectId, - keyFilename: pathToKey, }); // Check if the defined bucket exists. Being able to connect means the configuration is good @@ -59,7 +70,7 @@ export class GoogleGCSPublish implements PublisherBase { logger.error( `Could not retrieve metadata about the GCS bucket ${bucketName} in the GCP project ${projectId}. ` + 'Make sure the GCP project and the bucket exists and the access key located at the path ' + - "techdocs.publisher.googleGcs.pathToKey defined in app config has the role 'Storage Object Creator'. " + + "techdocs.publisher.googleGcs.credentials defined in app config has the role 'Storage Object Creator'. " + 'Refer to https://backstage.io/docs/features/techdocs/using-cloud-storage', ); throw new Error(`from GCS client library: ${reason.message}`); diff --git a/packages/techdocs-common/src/stages/publish/publish.test.ts b/packages/techdocs-common/src/stages/publish/publish.test.ts index 16e2225e46..244a606129 100644 --- a/packages/techdocs-common/src/stages/publish/publish.test.ts +++ b/packages/techdocs-common/src/stages/publish/publish.test.ts @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import mockFs from 'mock-fs'; import { getVoidLogger, PluginEndpointDiscovery, @@ -66,10 +65,6 @@ describe('Publisher', () => { }); it('should create google gcs publisher from config', () => { - mockFs({ - '/path/to/google-application-credentials.json': '{}', - }); - const mockConfig = ConfigReader.fromConfigs([ { context: '', @@ -79,7 +74,7 @@ describe('Publisher', () => { publisher: { type: 'googleGcs', googleGcs: { - pathToKey: '/path/to/google-application-credentials.json', + credentials: '{}', projectId: 'gcp-project-id', bucketName: 'bucketName', }, @@ -91,7 +86,5 @@ describe('Publisher', () => { const publisher = Publisher.fromConfig(mockConfig, logger, testDiscovery); expect(publisher).toBeInstanceOf(GoogleGCSPublish); - - mockFs.restore(); }); }); diff --git a/plugins/techdocs/package.json b/plugins/techdocs/package.json index da4c239f36..5b95bd64d2 100644 --- a/plugins/techdocs/package.json +++ b/plugins/techdocs/package.json @@ -107,7 +107,7 @@ "googleGcs": { "type": "object", "properties": { - "pathToKey": { + "credentials": { "type": "string", "visibility": "secret" },