From 2f77e24fe539ea87f3bb3f2e19b5e1cc35da8112 Mon Sep 17 00:00:00 2001 From: Andre Wanlin Date: Sun, 10 Mar 2024 14:42:00 +0100 Subject: [PATCH 1/2] Azure DevOps config is now optional Signed-off-by: Andre Wanlin --- .changeset/spicy-eels-cheat.md | 5 +++++ plugins/azure-devops-backend/README.md | 18 ++++++++---------- plugins/azure-devops-backend/config.d.ts | 3 ++- .../src/api/AzureDevOpsApi.ts | 5 +++++ .../azure-devops-backend/src/service/router.ts | 6 ++++++ 5 files changed, 26 insertions(+), 11 deletions(-) create mode 100644 .changeset/spicy-eels-cheat.md diff --git a/.changeset/spicy-eels-cheat.md b/.changeset/spicy-eels-cheat.md new file mode 100644 index 0000000000..c6572cb1ed --- /dev/null +++ b/.changeset/spicy-eels-cheat.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-azure-devops-backend': patch +--- + +The `azureDevOps` configuration section is now optional and the `azureDevOps.token` has been deprecated. Use `integrations.azure` instead, see the [Azure DevOps Locations](https://backstage.io/docs/integrations/azure/locations) documentation for more details. diff --git a/plugins/azure-devops-backend/README.md b/plugins/azure-devops-backend/README.md index 7c722dbe26..d15d740ab1 100644 --- a/plugins/azure-devops-backend/README.md +++ b/plugins/azure-devops-backend/README.md @@ -6,28 +6,26 @@ Simple plugin that proxies requests to the [Azure DevOps](https://docs.microsoft The following sections will help you get the Azure DevOps Backend plugin setup and running. -### Configuration +### Credentials -The Azure DevOps plugin requires the following YAML to be added to your `app-config.yaml`: +In order to support **Multiple Organizations** as well as **Service Principals** and **Managed Identity** the Azure DevOps plugin relies on the `integrations.azure` section of your `app-config.yaml` being properly configured to be able to access the needed credentials. More details on this can be found in the [Azure DevOps Locations](https://backstage.io/docs/integrations/azure/locations) documentation. + +### Single Organization Configuration + +For those with a single organization the Azure DevOps plugin requires the following YAML configuration to be added to your `app-config.yaml`: ```yaml azureDevOps: host: dev.azure.com - token: ${AZURE_TOKEN} organization: my-company ``` Configuration Details: -- `host` and `token` can be the same as the ones used for the `integration` section -- `AZURE_TOKEN` environment variable must be set to a [Personal Access Token](https://docs.microsoft.com/en-us/azure/devops/organizations/accounts/use-personal-access-tokens-to-authenticate?view=azure-devops&tabs=preview-page) with read access to both Code and Build +- `host` can be the same as the ones used for the `integration` section - `organization` is your Azure DevOps Services (cloud) Organization name or for Azure DevOps Server (on-premise) this will be your Collection name -#### Multi Organization & Service Principals - -To support cases where you have multiple Azure DevOps organizations and/or you want to use a Service Principal you will want to make sure to configure them in the `integrations.azure` section of your `app-config.yaml` as detailed in the [Azure DevOps Locations](https://backstage.io/docs/integrations/azure/locations) documentation. - -**Note:** You will still need to define the [configuration above](#configuration). +> Note: The credentials in this setup would still need to be defined in your `integrations.azure` section of your `app-config.yaml` as noted in the [Credentials](#credentials) section above. ### Up and Running diff --git a/plugins/azure-devops-backend/config.d.ts b/plugins/azure-devops-backend/config.d.ts index 86fefeeef9..7b85aad6be 100644 --- a/plugins/azure-devops-backend/config.d.ts +++ b/plugins/azure-devops-backend/config.d.ts @@ -18,7 +18,7 @@ export interface Config { /** * Configuration options for the azure-devops-backend plugin */ - azureDevOps: { + azureDevOps?: { /** * The hostname of the given Azure instance */ @@ -26,6 +26,7 @@ export interface Config { /** * Token used to authenticate requests. * @visibility secret + * @deprecated Use `integrations.azure` instead, see {@link https://backstage.io/docs/integrations/azure/locations} */ token: string; /** diff --git a/plugins/azure-devops-backend/src/api/AzureDevOpsApi.ts b/plugins/azure-devops-backend/src/api/AzureDevOpsApi.ts index cc5cad92b7..0376c82258 100644 --- a/plugins/azure-devops-backend/src/api/AzureDevOpsApi.ts +++ b/plugins/azure-devops-backend/src/api/AzureDevOpsApi.ts @@ -121,6 +121,11 @@ export class AzureDevOpsApi { // No credentials found for the provided host and org in the `integrations.azure` config section // use the fall back personal access token from `azureDevOps.token` const token = this.config.getString('azureDevOps.token'); + if (token) { + this.logger.warn( + "Using the token from 'azureDevOps.token' has been deprecated, use 'integrations.azure' instead, for more details see: https://backstage.io/docs/integrations/azure/locations", + ); + } authHandler = getPersonalAccessTokenHandler(token); } else { authHandler = getHandlerFromToken(credentials.token); diff --git a/plugins/azure-devops-backend/src/service/router.ts b/plugins/azure-devops-backend/src/service/router.ts index 239de78fbe..d81f4ff686 100644 --- a/plugins/azure-devops-backend/src/service/router.ts +++ b/plugins/azure-devops-backend/src/service/router.ts @@ -59,6 +59,12 @@ export async function createRouter( ): Promise { const { logger, reader, config, permissions } = options; + if (config.getString('azureDevOps.token')) { + logger.warn( + "The 'azureDevOps.token' has been deprecated, use 'integrations.azure' instead, for more details see: https://backstage.io/docs/integrations/azure/locations", + ); + } + const permissionIntegrationRouter = createPermissionIntegrationRouter({ permissions: azureDevOpsPermissions, }); From d54d3c674889a9533c89b79685ec64b5e2d4bfab Mon Sep 17 00:00:00 2001 From: Andre Wanlin Date: Mon, 11 Mar 2024 10:20:07 +0100 Subject: [PATCH 2/2] Made config truly optional Signed-off-by: Andre Wanlin --- .../src/api/AzureDevOpsApi.ts | 24 +++++++++++++------ 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/plugins/azure-devops-backend/src/api/AzureDevOpsApi.ts b/plugins/azure-devops-backend/src/api/AzureDevOpsApi.ts index 0376c82258..18bad8c330 100644 --- a/plugins/azure-devops-backend/src/api/AzureDevOpsApi.ts +++ b/plugins/azure-devops-backend/src/api/AzureDevOpsApi.ts @@ -108,10 +108,17 @@ export class AzureDevOpsApi { // If no host or org is provided we fall back to the values from the `azureDevOps` config section // these may have been setup in the `integrations.azure` config section // which is why use them here and not just falling back on them entirely - const validHost = host ?? this.config.getString('azureDevOps.host'); - const validOrg = org ?? this.config.getString('azureDevOps.organization'); - const url = `https://${validHost}/${encodeURIComponent(validOrg)}`; + const validHost = host ?? this.config.getOptionalString('azureDevOps.host'); + const validOrg = + org ?? this.config.getOptionalString('azureDevOps.organization'); + if (!validHost || !validOrg) { + throw new Error( + "No 'host' or 'org' provided in annotations or configuration, unable to retrieve needed credentials", + ); + } + + const url = `https://${validHost}/${encodeURIComponent(validOrg)}`; const credentials = await this.credentialsProvider.getCredentials({ url, }); @@ -120,12 +127,15 @@ export class AzureDevOpsApi { if (!credentials) { // No credentials found for the provided host and org in the `integrations.azure` config section // use the fall back personal access token from `azureDevOps.token` - const token = this.config.getString('azureDevOps.token'); - if (token) { - this.logger.warn( - "Using the token from 'azureDevOps.token' has been deprecated, use 'integrations.azure' instead, for more details see: https://backstage.io/docs/integrations/azure/locations", + const token = this.config.getOptionalString('azureDevOps.token'); + if (!token) { + throw new Error( + "No 'azureDevOps.token' provided in configuration and credentials were not found in 'integrations.azure', unable to proceed", ); } + this.logger.warn( + "Using the token from 'azureDevOps.token' has been deprecated, use 'integrations.azure' instead, for more details see: https://backstage.io/docs/integrations/azure/locations", + ); authHandler = getPersonalAccessTokenHandler(token); } else { authHandler = getHandlerFromToken(credentials.token);