From aa524a5377b38f582c2f1b90aca482347340153b Mon Sep 17 00:00:00 2001 From: James Turley Date: Tue, 9 Aug 2022 14:26:42 +0100 Subject: [PATCH] Add projectId config option to GCS techdocs publisher Fixes #13049 Signed-off-by: James Turley --- .changeset/gold-laws-attend.md | 6 ++++++ .github/vale/Vocab/Backstage/accept.txt | 1 + docs/features/techdocs/using-cloud-storage.md | 19 ++++++++++++++++++- plugins/techdocs-backend/config.d.ts | 7 +++++++ .../src/stages/publish/googleStorage.ts | 16 +++++++++++++++- 5 files changed, 47 insertions(+), 2 deletions(-) create mode 100644 .changeset/gold-laws-attend.md diff --git a/.changeset/gold-laws-attend.md b/.changeset/gold-laws-attend.md new file mode 100644 index 0000000000..c0d2123557 --- /dev/null +++ b/.changeset/gold-laws-attend.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-techdocs-backend': minor +'@backstage/plugin-techdocs-node': minor +--- + +Add projectId config option to GCP Cloud Storage techdocs publisher. This will allow users to override the project ID, instead of implicitly using the same one as found in a credentials bundle. diff --git a/.github/vale/Vocab/Backstage/accept.txt b/.github/vale/Vocab/Backstage/accept.txt index ae94912f38..4efdda88b5 100644 --- a/.github/vale/Vocab/Backstage/accept.txt +++ b/.github/vale/Vocab/Backstage/accept.txt @@ -235,6 +235,7 @@ preconfigured prepack Preprarer productional +projectId Protobuf proxying Proxying diff --git a/docs/features/techdocs/using-cloud-storage.md b/docs/features/techdocs/using-cloud-storage.md index 5a53961e81..66b4f09596 100644 --- a/docs/features/techdocs/using-cloud-storage.md +++ b/docs/features/techdocs/using-cloud-storage.md @@ -38,7 +38,9 @@ files from here to serve documentation in Backstage. Note that the bucket names are globally unique. Set the config `techdocs.publisher.googleGcs.bucketName` in your -`app-config.yaml` to the name of the bucket you just created. +`app-config.yaml` to the name of the bucket you just created. Set +`techdocs.publisher.googleGcs.projectId` to the ID of the Google Cloud project +that contains your bucket. ```yaml techdocs: @@ -46,6 +48,7 @@ techdocs: type: 'googleGcs' googleGcs: bucketName: 'name-of-techdocs-storage-bucket' + projectId: 'name-of-project' ``` **3a. (Recommended) Authentication using environment variable** @@ -98,6 +101,20 @@ techdocs: credentials: ${GOOGLE_APPLICATION_CREDENTIALS} ``` +Assuming the service account you are using was created in the same project as +the bucket, you do not need to set the `projectId` field. If not, you will +have to override it as with default credentials: + +```yaml +techdocs: + publisher: + type: 'googleGcs' + googleGcs: + bucketName: 'name-of-techdocs-storage-bucket' + credentials: ${GOOGLE_APPLICATION_CREDENTIALS} + projectId: 'name-of-project' +``` + **4. That's it!** Your Backstage app is now ready to use Google Cloud Storage for TechDocs, to diff --git a/plugins/techdocs-backend/config.d.ts b/plugins/techdocs-backend/config.d.ts index fdacc9cfbc..cb9d4ceabf 100644 --- a/plugins/techdocs-backend/config.d.ts +++ b/plugins/techdocs-backend/config.d.ts @@ -233,6 +233,13 @@ export interface Config { * @visibility secret */ credentials?: string; + /** + * (Optional) GCP project ID that contains the bucket. Should be + * set if credentials is not set, or if the service account in + * the credentials belongs to a different project to the bucket. + * @visibility backend + */ + projectId?: string; }; }; diff --git a/plugins/techdocs-node/src/stages/publish/googleStorage.ts b/plugins/techdocs-node/src/stages/publish/googleStorage.ts index 987dfc6f09..e62ff4f8b6 100644 --- a/plugins/techdocs-node/src/stages/publish/googleStorage.ts +++ b/plugins/techdocs-node/src/stages/publish/googleStorage.ts @@ -16,7 +16,12 @@ import { Entity, CompoundEntityRef } from '@backstage/catalog-model'; import { Config } from '@backstage/config'; import { assertError } from '@backstage/errors'; -import { File, FileExistsResponse, Storage } from '@google-cloud/storage'; +import { + File, + FileExistsResponse, + Storage, + StorageOptions, +} from '@google-cloud/storage'; import express from 'express'; import JSON5 from 'json5'; import path from 'path'; @@ -83,6 +88,9 @@ export class GoogleGCSPublish implements PublisherBase { const credentials = config.getOptionalString( 'techdocs.publisher.googleGcs.credentials', ); + const projectId = config.getOptionalString( + 'techdocs.publisher.googleGcs.projectId', + ); let credentialsJson: any = {}; if (credentials) { try { @@ -94,11 +102,17 @@ export class GoogleGCSPublish implements PublisherBase { } } + const clientOpts: StorageOptions = {}; + if (projectId) { + clientOpts.projectId = projectId; + } + const storageClient = new Storage({ ...(credentials && { projectId: credentialsJson.project_id, credentials: credentialsJson, }), + ...clientOpts, }); const legacyPathCasing =