@backstage/plugin-catalog-backend-module-azure 0.1.5 → 0.1.6-next.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # @backstage/plugin-catalog-backend-module-azure
2
2
 
3
+ ## 0.1.6-next.0
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies
8
+ - @backstage/backend-common@0.15.0-next.0
9
+ - @backstage/integration@1.3.0-next.0
10
+ - @backstage/backend-tasks@0.3.4-next.0
11
+ - @backstage/plugin-catalog-backend@1.3.1-next.0
12
+
3
13
  ## 0.1.5
4
14
 
5
15
  ### Patch Changes
package/dist/index.cjs.js CHANGED
@@ -50,7 +50,9 @@ async function codeSearch(azureConfig, org, project, repo, path) {
50
50
  })
51
51
  });
52
52
  if (response.status !== 200) {
53
- throw new Error(`Azure DevOps search failed with response status ${response.status}`);
53
+ throw new Error(
54
+ `Azure DevOps search failed with response status ${response.status}`
55
+ );
54
56
  }
55
57
  const body = await response.json();
56
58
  items = [...items, ...body.results];
@@ -81,18 +83,34 @@ class AzureDevOpsDiscoveryProcessor {
81
83
  }
82
84
  const azureConfig = (_a = this.integrations.azure.byUrl(location.target)) == null ? void 0 : _a.config;
83
85
  if (!azureConfig) {
84
- throw new Error(`There is no Azure integration that matches ${location.target}. Please add a configuration entry for it under integrations.azure`);
86
+ throw new Error(
87
+ `There is no Azure integration that matches ${location.target}. Please add a configuration entry for it under integrations.azure`
88
+ );
85
89
  }
86
- const { baseUrl, org, project, repo, catalogPath } = parseUrl(location.target);
87
- this.logger.info(`Reading Azure DevOps repositories from ${location.target}`);
88
- const files = await codeSearch(azureConfig, org, project, repo, catalogPath);
89
- this.logger.debug(`Found ${files.length} files in Azure DevOps from ${location.target}.`);
90
+ const { baseUrl, org, project, repo, catalogPath } = parseUrl(
91
+ location.target
92
+ );
93
+ this.logger.info(
94
+ `Reading Azure DevOps repositories from ${location.target}`
95
+ );
96
+ const files = await codeSearch(
97
+ azureConfig,
98
+ org,
99
+ project,
100
+ repo,
101
+ catalogPath
102
+ );
103
+ this.logger.debug(
104
+ `Found ${files.length} files in Azure DevOps from ${location.target}.`
105
+ );
90
106
  for (const file of files) {
91
- emit(pluginCatalogBackend.processingResult.location({
92
- type: "url",
93
- target: `${baseUrl}/${org}/${project}/_git/${file.repository.name}?path=${file.path}`,
94
- presence: "optional"
95
- }));
107
+ emit(
108
+ pluginCatalogBackend.processingResult.location({
109
+ type: "url",
110
+ target: `${baseUrl}/${org}/${project}/_git/${file.repository.name}?path=${file.path}`,
111
+ presence: "optional"
112
+ })
113
+ );
96
114
  }
97
115
  return true;
98
116
  }
@@ -123,7 +141,9 @@ function parseUrl(urlString) {
123
141
 
124
142
  function readAzureDevOpsConfigs(config) {
125
143
  const configs = [];
126
- const providerConfigs = config.getOptionalConfig("catalog.providers.azureDevOps");
144
+ const providerConfigs = config.getOptionalConfig(
145
+ "catalog.providers.azureDevOps"
146
+ );
127
147
  if (!providerConfigs) {
128
148
  return configs;
129
149
  }
@@ -160,11 +180,20 @@ class AzureDevOpsEntityProvider {
160
180
  static fromConfig(configRoot, options) {
161
181
  const providerConfigs = readAzureDevOpsConfigs(configRoot);
162
182
  return providerConfigs.map((providerConfig) => {
163
- const integration$1 = integration.ScmIntegrations.fromConfig(configRoot).azure.byHost(providerConfig.host);
183
+ const integration$1 = integration.ScmIntegrations.fromConfig(configRoot).azure.byHost(
184
+ providerConfig.host
185
+ );
164
186
  if (!integration$1) {
165
- throw new Error(`There is no Azure integration for host ${providerConfig.host}. Please add a configuration entry for it under integrations.azure`);
187
+ throw new Error(
188
+ `There is no Azure integration for host ${providerConfig.host}. Please add a configuration entry for it under integrations.azure`
189
+ );
166
190
  }
167
- return new AzureDevOpsEntityProvider(providerConfig, integration$1, options.logger, options.schedule);
191
+ return new AzureDevOpsEntityProvider(
192
+ providerConfig,
193
+ integration$1,
194
+ options.logger,
195
+ options.schedule
196
+ );
168
197
  });
169
198
  }
170
199
  createScheduleFn(schedule) {
@@ -199,7 +228,13 @@ class AzureDevOpsEntityProvider {
199
228
  throw new Error("Not initialized");
200
229
  }
201
230
  logger.info("Discovering Azure DevOps catalog files");
202
- const files = await codeSearch(this.integration.config, this.config.organization, this.config.project, this.config.repository, this.config.path);
231
+ const files = await codeSearch(
232
+ this.integration.config,
233
+ this.config.organization,
234
+ this.config.project,
235
+ this.config.repository,
236
+ this.config.path
237
+ );
203
238
  logger.info(`Discovered ${files.length} catalog files`);
204
239
  const locations = files.map((key) => this.createLocationSpec(key));
205
240
  await this.connection.applyMutation({
@@ -211,7 +246,9 @@ class AzureDevOpsEntityProvider {
211
246
  };
212
247
  })
213
248
  });
214
- logger.info(`Committed ${locations.length} locations for AzureDevOps catalog files`);
249
+ logger.info(
250
+ `Committed ${locations.length} locations for AzureDevOps catalog files`
251
+ );
215
252
  }
216
253
  createLocationSpec(file) {
217
254
  return {
@@ -222,7 +259,9 @@ class AzureDevOpsEntityProvider {
222
259
  }
223
260
  createObjectUrl(file) {
224
261
  const baseUrl = `https://${this.config.host}/${this.config.organization}/${this.config.project}`;
225
- return encodeURI(`${baseUrl}/_git/${file.repository.name}?path=${file.path}`);
262
+ return encodeURI(
263
+ `${baseUrl}/_git/${file.repository.name}?path=${file.path}`
264
+ );
226
265
  }
227
266
  }
228
267
 
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs.js","sources":["../src/lib/azure.ts","../src/processors/AzureDevOpsDiscoveryProcessor.ts","../src/providers/config.ts","../src/providers/AzureDevOpsEntityProvider.ts"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport fetch from 'node-fetch';\nimport {\n AzureIntegrationConfig,\n getAzureRequestOptions,\n} from '@backstage/integration';\n\nexport interface CodeSearchResponse {\n count: number;\n results: CodeSearchResultItem[];\n}\n\nexport interface CodeSearchResultItem {\n fileName: string;\n path: string;\n repository: {\n name: string;\n };\n}\n\nconst isCloud = (host: string) => host === 'dev.azure.com';\nconst PAGE_SIZE = 1000;\n\n// codeSearch returns all files that matches the given search path.\nexport async function codeSearch(\n azureConfig: AzureIntegrationConfig,\n org: string,\n project: string,\n repo: string,\n path: string,\n): Promise<CodeSearchResultItem[]> {\n const searchBaseUrl = isCloud(azureConfig.host)\n ? 'https://almsearch.dev.azure.com'\n : `https://${azureConfig.host}`;\n const searchUrl = `${searchBaseUrl}/${org}/${project}/_apis/search/codesearchresults?api-version=6.0-preview.1`;\n\n let items: CodeSearchResultItem[] = [];\n let hasMorePages = true;\n\n do {\n const response = await fetch(searchUrl, {\n ...getAzureRequestOptions(azureConfig, {\n 'Content-Type': 'application/json',\n }),\n method: 'POST',\n body: JSON.stringify({\n searchText: `path:${path} repo:${repo || '*'}`,\n $skip: items.length,\n $top: PAGE_SIZE,\n }),\n });\n\n if (response.status !== 200) {\n throw new Error(\n `Azure DevOps search failed with response status ${response.status}`,\n );\n }\n\n const body: CodeSearchResponse = await response.json();\n items = [...items, ...body.results];\n hasMorePages = body.count > items.length;\n } while (hasMorePages);\n\n return items;\n}\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Config } from '@backstage/config';\nimport {\n ScmIntegrationRegistry,\n ScmIntegrations,\n} from '@backstage/integration';\nimport {\n CatalogProcessor,\n CatalogProcessorEmit,\n LocationSpec,\n processingResult,\n} from '@backstage/plugin-catalog-backend';\nimport { Logger } from 'winston';\nimport { codeSearch } from '../lib';\n\n/**\n * Extracts repositories out of an Azure DevOps org.\n *\n * The following will create locations for all projects which have a catalog-info.yaml\n * on the default branch. The first is shorthand for the second.\n *\n * target: \"https://dev.azure.com/org/project\"\n * or\n * target: https://dev.azure.com/org/project?path=/catalog-info.yaml\n *\n * You may also explicitly specify a single repo:\n *\n * target: https://dev.azure.com/org/project/_git/repo\n *\n * @public\n **/\nexport class AzureDevOpsDiscoveryProcessor implements CatalogProcessor {\n private readonly integrations: ScmIntegrationRegistry;\n private readonly logger: Logger;\n\n static fromConfig(config: Config, options: { logger: Logger }) {\n const integrations = ScmIntegrations.fromConfig(config);\n\n return new AzureDevOpsDiscoveryProcessor({\n ...options,\n integrations,\n });\n }\n\n constructor(options: {\n integrations: ScmIntegrationRegistry;\n logger: Logger;\n }) {\n this.integrations = options.integrations;\n this.logger = options.logger;\n }\n\n getProcessorName(): string {\n return 'AzureDevOpsDiscoveryProcessor';\n }\n\n async readLocation(\n location: LocationSpec,\n _optional: boolean,\n emit: CatalogProcessorEmit,\n ): Promise<boolean> {\n if (location.type !== 'azure-discovery') {\n return false;\n }\n\n const azureConfig = this.integrations.azure.byUrl(location.target)?.config;\n if (!azureConfig) {\n throw new Error(\n `There is no Azure integration that matches ${location.target}. Please add a configuration entry for it under integrations.azure`,\n );\n }\n\n const { baseUrl, org, project, repo, catalogPath } = parseUrl(\n location.target,\n );\n this.logger.info(\n `Reading Azure DevOps repositories from ${location.target}`,\n );\n\n const files = await codeSearch(\n azureConfig,\n org,\n project,\n repo,\n catalogPath,\n );\n\n this.logger.debug(\n `Found ${files.length} files in Azure DevOps from ${location.target}.`,\n );\n\n for (const file of files) {\n emit(\n processingResult.location({\n type: 'url',\n target: `${baseUrl}/${org}/${project}/_git/${file.repository.name}?path=${file.path}`,\n // Not all locations may actually exist, since the user defined them as a wildcard pattern.\n // Thus, we emit them as optional and let the downstream processor find them while not outputting\n // an error if it couldn't.\n presence: 'optional',\n }),\n );\n }\n\n return true;\n }\n}\n\n/**\n * parseUrl extracts segments from the Azure DevOps URL.\n **/\nexport function parseUrl(urlString: string): {\n baseUrl: string;\n org: string;\n project: string;\n repo: string;\n catalogPath: string;\n} {\n const url = new URL(urlString);\n const path = url.pathname.substr(1).split('/');\n\n const catalogPath = url.searchParams.get('path') || '/catalog-info.yaml';\n\n if (path.length === 2 && path[0].length && path[1].length) {\n return {\n baseUrl: url.origin,\n org: decodeURIComponent(path[0]),\n project: decodeURIComponent(path[1]),\n repo: '',\n catalogPath,\n };\n } else if (\n path.length === 4 &&\n path[0].length &&\n path[1].length &&\n path[2].length &&\n path[3].length\n ) {\n return {\n baseUrl: url.origin,\n org: decodeURIComponent(path[0]),\n project: decodeURIComponent(path[1]),\n repo: decodeURIComponent(path[3]),\n catalogPath,\n };\n }\n\n throw new Error(`Failed to parse ${urlString}`);\n}\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Config } from '@backstage/config';\nimport { AzureDevOpsConfig } from './types';\n\nexport function readAzureDevOpsConfigs(config: Config): AzureDevOpsConfig[] {\n const configs: AzureDevOpsConfig[] = [];\n\n const providerConfigs = config.getOptionalConfig(\n 'catalog.providers.azureDevOps',\n );\n\n if (!providerConfigs) {\n return configs;\n }\n\n for (const id of providerConfigs.keys()) {\n configs.push(readAzureDevOpsConfig(id, providerConfigs.getConfig(id)));\n }\n\n return configs;\n}\n\nfunction readAzureDevOpsConfig(id: string, config: Config): AzureDevOpsConfig {\n const organization = config.getString('organization');\n const project = config.getString('project');\n const host = config.getOptionalString('host') || 'dev.azure.com';\n const repository = config.getOptionalString('repository') || '*';\n const path = config.getOptionalString('path') || '/catalog-info.yaml';\n\n return {\n id,\n host,\n organization,\n project,\n repository,\n path,\n };\n}\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { TaskRunner } from '@backstage/backend-tasks';\nimport { Config } from '@backstage/config';\nimport { AzureIntegration, ScmIntegrations } from '@backstage/integration';\nimport {\n EntityProvider,\n EntityProviderConnection,\n LocationSpec,\n locationSpecToLocationEntity,\n} from '@backstage/plugin-catalog-backend';\nimport { readAzureDevOpsConfigs } from './config';\nimport { Logger } from 'winston';\nimport { AzureDevOpsConfig } from './types';\nimport * as uuid from 'uuid';\nimport { codeSearch, CodeSearchResultItem } from '../lib';\n\n/**\n * Provider which discovers catalog files within an Azure DevOps repositories.\n *\n * Use `AzureDevOpsEntityProvider.fromConfig(...)` to create instances.\n *\n * @public\n */\nexport class AzureDevOpsEntityProvider implements EntityProvider {\n private readonly logger: Logger;\n private readonly scheduleFn: () => Promise<void>;\n private connection?: EntityProviderConnection;\n\n static fromConfig(\n configRoot: Config,\n options: {\n logger: Logger;\n schedule: TaskRunner;\n },\n ): AzureDevOpsEntityProvider[] {\n const providerConfigs = readAzureDevOpsConfigs(configRoot);\n\n return providerConfigs.map(providerConfig => {\n const integration = ScmIntegrations.fromConfig(configRoot).azure.byHost(\n providerConfig.host,\n );\n\n if (!integration) {\n throw new Error(\n `There is no Azure integration for host ${providerConfig.host}. Please add a configuration entry for it under integrations.azure`,\n );\n }\n\n return new AzureDevOpsEntityProvider(\n providerConfig,\n integration,\n options.logger,\n options.schedule,\n );\n });\n }\n\n private constructor(\n private readonly config: AzureDevOpsConfig,\n private readonly integration: AzureIntegration,\n logger: Logger,\n schedule: TaskRunner,\n ) {\n this.logger = logger.child({\n target: this.getProviderName(),\n });\n\n this.scheduleFn = this.createScheduleFn(schedule);\n }\n\n private createScheduleFn(schedule: TaskRunner): () => Promise<void> {\n return async () => {\n const taskId = `${this.getProviderName()}:refresh`;\n return schedule.run({\n id: taskId,\n fn: async () => {\n const logger = this.logger.child({\n class: AzureDevOpsEntityProvider.prototype.constructor.name,\n taskId,\n taskInstanceId: uuid.v4(),\n });\n\n try {\n await this.refresh(logger);\n } catch (error) {\n logger.error(error);\n }\n },\n });\n };\n }\n\n /** {@inheritdoc @backstage/plugin-catalog-backend#EntityProvider.getProviderName} */\n getProviderName(): string {\n return `AzureDevOpsEntityProvider:${this.config.id}`;\n }\n\n /** {@inheritdoc @backstage/plugin-catalog-backend#EntityProvider.connect} */\n async connect(connection: EntityProviderConnection): Promise<void> {\n this.connection = connection;\n await this.scheduleFn();\n }\n\n async refresh(logger: Logger) {\n if (!this.connection) {\n throw new Error('Not initialized');\n }\n\n logger.info('Discovering Azure DevOps catalog files');\n\n const files = await codeSearch(\n this.integration.config,\n this.config.organization,\n this.config.project,\n this.config.repository,\n this.config.path,\n );\n\n logger.info(`Discovered ${files.length} catalog files`);\n\n const locations = files.map(key => this.createLocationSpec(key));\n\n await this.connection.applyMutation({\n type: 'full',\n entities: locations.map(location => {\n return {\n locationKey: this.getProviderName(),\n entity: locationSpecToLocationEntity({ location }),\n };\n }),\n });\n\n logger.info(\n `Committed ${locations.length} locations for AzureDevOps catalog files`,\n );\n }\n\n private createLocationSpec(file: CodeSearchResultItem): LocationSpec {\n return {\n type: 'url',\n target: this.createObjectUrl(file),\n presence: 'required',\n };\n }\n\n private createObjectUrl(file: CodeSearchResultItem): string {\n const baseUrl = `https://${this.config.host}/${this.config.organization}/${this.config.project}`;\n return encodeURI(\n `${baseUrl}/_git/${file.repository.name}?path=${file.path}`,\n );\n }\n}\n"],"names":["fetch","getAzureRequestOptions","ScmIntegrations","processingResult","integration","uuid","locationSpecToLocationEntity"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs.js","sources":["../src/lib/azure.ts","../src/processors/AzureDevOpsDiscoveryProcessor.ts","../src/providers/config.ts","../src/providers/AzureDevOpsEntityProvider.ts"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport fetch from 'node-fetch';\nimport {\n AzureIntegrationConfig,\n getAzureRequestOptions,\n} from '@backstage/integration';\n\nexport interface CodeSearchResponse {\n count: number;\n results: CodeSearchResultItem[];\n}\n\nexport interface CodeSearchResultItem {\n fileName: string;\n path: string;\n repository: {\n name: string;\n };\n}\n\nconst isCloud = (host: string) => host === 'dev.azure.com';\nconst PAGE_SIZE = 1000;\n\n// codeSearch returns all files that matches the given search path.\nexport async function codeSearch(\n azureConfig: AzureIntegrationConfig,\n org: string,\n project: string,\n repo: string,\n path: string,\n): Promise<CodeSearchResultItem[]> {\n const searchBaseUrl = isCloud(azureConfig.host)\n ? 'https://almsearch.dev.azure.com'\n : `https://${azureConfig.host}`;\n const searchUrl = `${searchBaseUrl}/${org}/${project}/_apis/search/codesearchresults?api-version=6.0-preview.1`;\n\n let items: CodeSearchResultItem[] = [];\n let hasMorePages = true;\n\n do {\n const response = await fetch(searchUrl, {\n ...getAzureRequestOptions(azureConfig, {\n 'Content-Type': 'application/json',\n }),\n method: 'POST',\n body: JSON.stringify({\n searchText: `path:${path} repo:${repo || '*'}`,\n $skip: items.length,\n $top: PAGE_SIZE,\n }),\n });\n\n if (response.status !== 200) {\n throw new Error(\n `Azure DevOps search failed with response status ${response.status}`,\n );\n }\n\n const body: CodeSearchResponse = await response.json();\n items = [...items, ...body.results];\n hasMorePages = body.count > items.length;\n } while (hasMorePages);\n\n return items;\n}\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Config } from '@backstage/config';\nimport {\n ScmIntegrationRegistry,\n ScmIntegrations,\n} from '@backstage/integration';\nimport {\n CatalogProcessor,\n CatalogProcessorEmit,\n LocationSpec,\n processingResult,\n} from '@backstage/plugin-catalog-backend';\nimport { Logger } from 'winston';\nimport { codeSearch } from '../lib';\n\n/**\n * Extracts repositories out of an Azure DevOps org.\n *\n * The following will create locations for all projects which have a catalog-info.yaml\n * on the default branch. The first is shorthand for the second.\n *\n * target: \"https://dev.azure.com/org/project\"\n * or\n * target: https://dev.azure.com/org/project?path=/catalog-info.yaml\n *\n * You may also explicitly specify a single repo:\n *\n * target: https://dev.azure.com/org/project/_git/repo\n *\n * @public\n **/\nexport class AzureDevOpsDiscoveryProcessor implements CatalogProcessor {\n private readonly integrations: ScmIntegrationRegistry;\n private readonly logger: Logger;\n\n static fromConfig(config: Config, options: { logger: Logger }) {\n const integrations = ScmIntegrations.fromConfig(config);\n\n return new AzureDevOpsDiscoveryProcessor({\n ...options,\n integrations,\n });\n }\n\n constructor(options: {\n integrations: ScmIntegrationRegistry;\n logger: Logger;\n }) {\n this.integrations = options.integrations;\n this.logger = options.logger;\n }\n\n getProcessorName(): string {\n return 'AzureDevOpsDiscoveryProcessor';\n }\n\n async readLocation(\n location: LocationSpec,\n _optional: boolean,\n emit: CatalogProcessorEmit,\n ): Promise<boolean> {\n if (location.type !== 'azure-discovery') {\n return false;\n }\n\n const azureConfig = this.integrations.azure.byUrl(location.target)?.config;\n if (!azureConfig) {\n throw new Error(\n `There is no Azure integration that matches ${location.target}. Please add a configuration entry for it under integrations.azure`,\n );\n }\n\n const { baseUrl, org, project, repo, catalogPath } = parseUrl(\n location.target,\n );\n this.logger.info(\n `Reading Azure DevOps repositories from ${location.target}`,\n );\n\n const files = await codeSearch(\n azureConfig,\n org,\n project,\n repo,\n catalogPath,\n );\n\n this.logger.debug(\n `Found ${files.length} files in Azure DevOps from ${location.target}.`,\n );\n\n for (const file of files) {\n emit(\n processingResult.location({\n type: 'url',\n target: `${baseUrl}/${org}/${project}/_git/${file.repository.name}?path=${file.path}`,\n // Not all locations may actually exist, since the user defined them as a wildcard pattern.\n // Thus, we emit them as optional and let the downstream processor find them while not outputting\n // an error if it couldn't.\n presence: 'optional',\n }),\n );\n }\n\n return true;\n }\n}\n\n/**\n * parseUrl extracts segments from the Azure DevOps URL.\n **/\nexport function parseUrl(urlString: string): {\n baseUrl: string;\n org: string;\n project: string;\n repo: string;\n catalogPath: string;\n} {\n const url = new URL(urlString);\n const path = url.pathname.substr(1).split('/');\n\n const catalogPath = url.searchParams.get('path') || '/catalog-info.yaml';\n\n if (path.length === 2 && path[0].length && path[1].length) {\n return {\n baseUrl: url.origin,\n org: decodeURIComponent(path[0]),\n project: decodeURIComponent(path[1]),\n repo: '',\n catalogPath,\n };\n } else if (\n path.length === 4 &&\n path[0].length &&\n path[1].length &&\n path[2].length &&\n path[3].length\n ) {\n return {\n baseUrl: url.origin,\n org: decodeURIComponent(path[0]),\n project: decodeURIComponent(path[1]),\n repo: decodeURIComponent(path[3]),\n catalogPath,\n };\n }\n\n throw new Error(`Failed to parse ${urlString}`);\n}\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Config } from '@backstage/config';\nimport { AzureDevOpsConfig } from './types';\n\nexport function readAzureDevOpsConfigs(config: Config): AzureDevOpsConfig[] {\n const configs: AzureDevOpsConfig[] = [];\n\n const providerConfigs = config.getOptionalConfig(\n 'catalog.providers.azureDevOps',\n );\n\n if (!providerConfigs) {\n return configs;\n }\n\n for (const id of providerConfigs.keys()) {\n configs.push(readAzureDevOpsConfig(id, providerConfigs.getConfig(id)));\n }\n\n return configs;\n}\n\nfunction readAzureDevOpsConfig(id: string, config: Config): AzureDevOpsConfig {\n const organization = config.getString('organization');\n const project = config.getString('project');\n const host = config.getOptionalString('host') || 'dev.azure.com';\n const repository = config.getOptionalString('repository') || '*';\n const path = config.getOptionalString('path') || '/catalog-info.yaml';\n\n return {\n id,\n host,\n organization,\n project,\n repository,\n path,\n };\n}\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { TaskRunner } from '@backstage/backend-tasks';\nimport { Config } from '@backstage/config';\nimport { AzureIntegration, ScmIntegrations } from '@backstage/integration';\nimport {\n EntityProvider,\n EntityProviderConnection,\n LocationSpec,\n locationSpecToLocationEntity,\n} from '@backstage/plugin-catalog-backend';\nimport { readAzureDevOpsConfigs } from './config';\nimport { Logger } from 'winston';\nimport { AzureDevOpsConfig } from './types';\nimport * as uuid from 'uuid';\nimport { codeSearch, CodeSearchResultItem } from '../lib';\n\n/**\n * Provider which discovers catalog files within an Azure DevOps repositories.\n *\n * Use `AzureDevOpsEntityProvider.fromConfig(...)` to create instances.\n *\n * @public\n */\nexport class AzureDevOpsEntityProvider implements EntityProvider {\n private readonly logger: Logger;\n private readonly scheduleFn: () => Promise<void>;\n private connection?: EntityProviderConnection;\n\n static fromConfig(\n configRoot: Config,\n options: {\n logger: Logger;\n schedule: TaskRunner;\n },\n ): AzureDevOpsEntityProvider[] {\n const providerConfigs = readAzureDevOpsConfigs(configRoot);\n\n return providerConfigs.map(providerConfig => {\n const integration = ScmIntegrations.fromConfig(configRoot).azure.byHost(\n providerConfig.host,\n );\n\n if (!integration) {\n throw new Error(\n `There is no Azure integration for host ${providerConfig.host}. Please add a configuration entry for it under integrations.azure`,\n );\n }\n\n return new AzureDevOpsEntityProvider(\n providerConfig,\n integration,\n options.logger,\n options.schedule,\n );\n });\n }\n\n private constructor(\n private readonly config: AzureDevOpsConfig,\n private readonly integration: AzureIntegration,\n logger: Logger,\n schedule: TaskRunner,\n ) {\n this.logger = logger.child({\n target: this.getProviderName(),\n });\n\n this.scheduleFn = this.createScheduleFn(schedule);\n }\n\n private createScheduleFn(schedule: TaskRunner): () => Promise<void> {\n return async () => {\n const taskId = `${this.getProviderName()}:refresh`;\n return schedule.run({\n id: taskId,\n fn: async () => {\n const logger = this.logger.child({\n class: AzureDevOpsEntityProvider.prototype.constructor.name,\n taskId,\n taskInstanceId: uuid.v4(),\n });\n\n try {\n await this.refresh(logger);\n } catch (error) {\n logger.error(error);\n }\n },\n });\n };\n }\n\n /** {@inheritdoc @backstage/plugin-catalog-backend#EntityProvider.getProviderName} */\n getProviderName(): string {\n return `AzureDevOpsEntityProvider:${this.config.id}`;\n }\n\n /** {@inheritdoc @backstage/plugin-catalog-backend#EntityProvider.connect} */\n async connect(connection: EntityProviderConnection): Promise<void> {\n this.connection = connection;\n await this.scheduleFn();\n }\n\n async refresh(logger: Logger) {\n if (!this.connection) {\n throw new Error('Not initialized');\n }\n\n logger.info('Discovering Azure DevOps catalog files');\n\n const files = await codeSearch(\n this.integration.config,\n this.config.organization,\n this.config.project,\n this.config.repository,\n this.config.path,\n );\n\n logger.info(`Discovered ${files.length} catalog files`);\n\n const locations = files.map(key => this.createLocationSpec(key));\n\n await this.connection.applyMutation({\n type: 'full',\n entities: locations.map(location => {\n return {\n locationKey: this.getProviderName(),\n entity: locationSpecToLocationEntity({ location }),\n };\n }),\n });\n\n logger.info(\n `Committed ${locations.length} locations for AzureDevOps catalog files`,\n );\n }\n\n private createLocationSpec(file: CodeSearchResultItem): LocationSpec {\n return {\n type: 'url',\n target: this.createObjectUrl(file),\n presence: 'required',\n };\n }\n\n private createObjectUrl(file: CodeSearchResultItem): string {\n const baseUrl = `https://${this.config.host}/${this.config.organization}/${this.config.project}`;\n return encodeURI(\n `${baseUrl}/_git/${file.repository.name}?path=${file.path}`,\n );\n }\n}\n"],"names":["fetch","getAzureRequestOptions","ScmIntegrations","processingResult","integration","uuid","locationSpecToLocationEntity"],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@backstage/plugin-catalog-backend-module-azure",
3
3
  "description": "A Backstage catalog backend module that helps integrate towards Azure",
4
- "version": "0.1.5",
4
+ "version": "0.1.6-next.0",
5
5
  "main": "dist/index.cjs.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "license": "Apache-2.0",
@@ -33,13 +33,13 @@
33
33
  "start": "backstage-cli package start"
34
34
  },
35
35
  "dependencies": {
36
- "@backstage/backend-common": "^0.14.1",
37
- "@backstage/backend-tasks": "^0.3.3",
36
+ "@backstage/backend-common": "^0.15.0-next.0",
37
+ "@backstage/backend-tasks": "^0.3.4-next.0",
38
38
  "@backstage/catalog-model": "^1.1.0",
39
39
  "@backstage/config": "^1.0.1",
40
40
  "@backstage/errors": "^1.1.0",
41
- "@backstage/integration": "^1.2.2",
42
- "@backstage/plugin-catalog-backend": "^1.3.0",
41
+ "@backstage/integration": "^1.3.0-next.0",
42
+ "@backstage/plugin-catalog-backend": "^1.3.1-next.0",
43
43
  "@backstage/types": "^1.0.0",
44
44
  "lodash": "^4.17.21",
45
45
  "msw": "^0.44.0",
@@ -48,8 +48,8 @@
48
48
  "winston": "^3.2.1"
49
49
  },
50
50
  "devDependencies": {
51
- "@backstage/backend-test-utils": "^0.1.26",
52
- "@backstage/cli": "^0.18.0",
51
+ "@backstage/backend-test-utils": "^0.1.27-next.0",
52
+ "@backstage/cli": "^0.18.1-next.0",
53
53
  "@types/lodash": "^4.14.151"
54
54
  },
55
55
  "files": [
@@ -57,5 +57,5 @@
57
57
  "config.d.ts"
58
58
  ],
59
59
  "configSchema": "config.d.ts",
60
- "gitHead": "999878d8f1ae30f6a15925816af2016cb9d717a1"
60
+ "gitHead": "fc3229c49caf6eced02ed9516199015bf4682664"
61
61
  }