diff --git a/.changeset/pretty-otters-whisper.md b/.changeset/pretty-otters-whisper.md new file mode 100644 index 0000000000..7019596b38 --- /dev/null +++ b/.changeset/pretty-otters-whisper.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-techdocs-node': minor +'@backstage/plugin-techdocs-backend': minor +--- + +Add a `techdocs.publisher.azureBlobStorage.connectionString` app-config setting, which can be leveraged for improved Azurite support. diff --git a/docs/features/techdocs/configuration.md b/docs/features/techdocs/configuration.md index f567bfbac9..a861a50c87 100644 --- a/docs/features/techdocs/configuration.md +++ b/docs/features/techdocs/configuration.md @@ -167,6 +167,12 @@ techdocs: # (Required) Azure Blob Storage Container Name containerName: 'techdocs-storage' + # (Optional) Azure blob storage connection string. + # Can be useful for local testing through azurite + # Defaults to undefined + # if provided, takes higher priority, 'techdocs.publisher.azureBlobStorage.credentials' will become irrelevant + connectionString: '' + # (Required) An account name is required to write to a storage blob container. # https://docs.microsoft.com/en-us/rest/api/storageservices/authorize-with-shared-key credentials: diff --git a/plugins/techdocs-backend/config.d.ts b/plugins/techdocs-backend/config.d.ts index 9ad2594ffd..abc74f796a 100644 --- a/plugins/techdocs-backend/config.d.ts +++ b/plugins/techdocs-backend/config.d.ts @@ -203,10 +203,15 @@ export interface Config { */ azureBlobStorage?: { /** - * (Required) Credentials used to access a storage container. + * (Optional) Connection string of the storage container. * @visibility secret */ - credentials: { + connectionString?: string; + /** + * (Optional) Credentials used to access a storage container. + * @visibility secret + */ + credentials?: { /** * Account access name * @visibility secret diff --git a/plugins/techdocs-node/src/stages/publish/azureBlobStorage.ts b/plugins/techdocs-node/src/stages/publish/azureBlobStorage.ts index bcbc10a94d..39a50e963a 100644 --- a/plugins/techdocs-node/src/stages/publish/azureBlobStorage.ts +++ b/plugins/techdocs-node/src/stages/publish/azureBlobStorage.ts @@ -66,6 +66,7 @@ export class AzureBlobStoragePublish implements PublisherBase { } static fromConfig(config: Config, logger: Logger): PublisherBase { + let storageClient: BlobServiceClient; let containerName = ''; try { containerName = config.getString( @@ -78,41 +79,53 @@ export class AzureBlobStoragePublish implements PublisherBase { ); } - let accountName = ''; - try { - accountName = config.getString( - 'techdocs.publisher.azureBlobStorage.credentials.accountName', - ); - } catch (error) { - throw new Error( - "Since techdocs.publisher.type is set to 'azureBlobStorage' in your app config, " + - 'techdocs.publisher.azureBlobStorage.credentials.accountName is required.', - ); - } - - // Credentials is an optional config. If missing, default Azure Blob Storage environment variables will be used. - // https://docs.microsoft.com/en-us/azure/storage/common/storage-auth-aad-app - const accountKey = config.getOptionalString( - 'techdocs.publisher.azureBlobStorage.credentials.accountKey', - ); - - let credential; - if (accountKey) { - credential = new StorageSharedKeyCredential(accountName, accountKey); - } else { - credential = new DefaultAzureCredential(); - } - - const storageClient = new BlobServiceClient( - `https://${accountName}.blob.core.windows.net`, - credential, - ); - const legacyPathCasing = config.getOptionalBoolean( 'techdocs.legacyUseCaseSensitiveTripletPaths', ) || false; + // Give more priority for connectionString, if configured, return the AzureBlobStoragePublish object here itself + const connectionStringKey = + 'techdocs.publisher.azureBlobStorage.connectionString'; + const connectionString = config.getOptionalString(connectionStringKey); + + if (connectionString) { + logger.info( + `Using '${connectionStringKey}' configuration to create storage client`, + ); + storageClient = BlobServiceClient.fromConnectionString(connectionString); + } else { + let accountName = ''; + try { + accountName = config.getString( + 'techdocs.publisher.azureBlobStorage.credentials.accountName', + ); + } catch (error) { + throw new Error( + "Since techdocs.publisher.type is set to 'azureBlobStorage' in your app config, " + + 'techdocs.publisher.azureBlobStorage.credentials.accountName is required.', + ); + } + + // Credentials is an optional config. If missing, default Azure Blob Storage environment variables will be used. + // https://docs.microsoft.com/en-us/azure/storage/common/storage-auth-aad-app + const accountKey = config.getOptionalString( + 'techdocs.publisher.azureBlobStorage.credentials.accountKey', + ); + + let credential; + if (accountKey) { + credential = new StorageSharedKeyCredential(accountName, accountKey); + } else { + credential = new DefaultAzureCredential(); + } + + storageClient = new BlobServiceClient( + `https://${accountName}.blob.core.windows.net`, + credential, + ); + } + return new AzureBlobStoragePublish({ storageClient: storageClient, containerName: containerName,