@red-hat-developer-hub/backstage-plugin-bulk-import-backend 7.3.7 → 8.0.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 +12 -0
- package/config.schema.json +21 -0
- package/dist/catalog/catalogHttpClient.cjs.js +43 -71
- package/dist/catalog/catalogHttpClient.cjs.js.map +1 -1
- package/dist/helpers/auth.cjs.js +0 -8
- package/dist/helpers/auth.cjs.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/plugin.cjs.js +8 -4
- package/dist/plugin.cjs.js.map +1 -1
- package/dist/service/handlers/import/bulkImports.cjs.js.map +1 -1
- package/dist/service/router.cjs.js +2 -10
- package/dist/service/router.cjs.js.map +1 -1
- package/package.json +19 -22
- package/config.d.ts +0 -30
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @red-hat-developer-hub/backstage-plugin-bulk-import-backend
|
|
2
2
|
|
|
3
|
+
## 8.0.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 02db099: Backstage version bump to v1.52.0
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- 8eb345e: Updated dependency `js-yaml` to `^4.3.0`.
|
|
12
|
+
- Updated dependencies [02db099]
|
|
13
|
+
- @red-hat-developer-hub/backstage-plugin-bulk-import-common@8.0.0
|
|
14
|
+
|
|
3
15
|
## 7.3.7
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"type": "object",
|
|
4
|
+
"properties": {
|
|
5
|
+
"bulkImport": {
|
|
6
|
+
"type": "object",
|
|
7
|
+
"properties": {
|
|
8
|
+
"importTemplate": {
|
|
9
|
+
"type": "string",
|
|
10
|
+
"description": "The name of the scaffolder template or entity reference to execute for importing a repository.",
|
|
11
|
+
"visibility": "backend"
|
|
12
|
+
},
|
|
13
|
+
"orchestratorWorkflow": {
|
|
14
|
+
"type": "string",
|
|
15
|
+
"description": "The orchestrator workflow id to execute for importing a repository.",
|
|
16
|
+
"visibility": "backend"
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -1,53 +1,43 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
require('@backstage/errors');
|
|
4
|
+
require('@backstage/plugin-permission-common');
|
|
5
|
+
require('@red-hat-developer-hub/backstage-plugin-bulk-import-common');
|
|
6
|
+
require('just-kebab-case');
|
|
5
7
|
var loggingUtils = require('../helpers/loggingUtils.cjs.js');
|
|
6
8
|
require('@backstage/catalog-model');
|
|
7
|
-
require('@backstage/errors');
|
|
8
9
|
require('git-url-parse');
|
|
9
10
|
var catalogUtils = require('./catalogUtils.cjs.js');
|
|
10
11
|
|
|
11
|
-
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
|
|
12
|
-
|
|
13
|
-
var fetch__default = /*#__PURE__*/_interopDefaultCompat(fetch);
|
|
14
|
-
|
|
15
12
|
class CatalogHttpClient {
|
|
16
13
|
logger;
|
|
17
14
|
config;
|
|
18
|
-
discovery;
|
|
19
15
|
auth;
|
|
20
|
-
|
|
16
|
+
catalog;
|
|
21
17
|
constructor(deps) {
|
|
22
18
|
this.logger = deps.logger;
|
|
23
19
|
this.config = deps.config;
|
|
24
|
-
this.discovery = deps.discovery;
|
|
25
20
|
this.auth = deps.auth;
|
|
26
|
-
this.
|
|
21
|
+
this.catalog = deps.catalog;
|
|
22
|
+
}
|
|
23
|
+
async getCredentials() {
|
|
24
|
+
return this.auth.getOwnServiceCredentials();
|
|
27
25
|
}
|
|
28
26
|
// Wrapper for https://backstage.io/docs/features/software-catalog/software-catalog-api/#post-analyze-location
|
|
29
27
|
async analyzeLocation(repoUrl) {
|
|
30
28
|
this.logger.debug(`Forwarding request to analyze location: ${repoUrl}`);
|
|
31
|
-
const response = await
|
|
32
|
-
`${await this.discovery.getBaseUrl("catalog")}/analyze-location`,
|
|
29
|
+
const response = await this.catalog.analyzeLocation(
|
|
33
30
|
{
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
method: "POST",
|
|
42
|
-
body: JSON.stringify({
|
|
43
|
-
location: {
|
|
44
|
-
type: "github",
|
|
45
|
-
target: repoUrl
|
|
46
|
-
}
|
|
47
|
-
})
|
|
31
|
+
location: {
|
|
32
|
+
type: "github",
|
|
33
|
+
target: repoUrl
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
credentials: await this.getCredentials()
|
|
48
38
|
}
|
|
49
39
|
);
|
|
50
|
-
return
|
|
40
|
+
return response.generateEntities ?? [];
|
|
51
41
|
}
|
|
52
42
|
async listCatalogUrlLocations(search, pageNumber, pageSize) {
|
|
53
43
|
const byId = await this.listCatalogUrlLocationsById(
|
|
@@ -80,27 +70,19 @@ class CatalogHttpClient {
|
|
|
80
70
|
};
|
|
81
71
|
}
|
|
82
72
|
async listCatalogUrlLocationsByIdFromLocationsEndpoint(search) {
|
|
83
|
-
const
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
"catalog"
|
|
90
|
-
)}`
|
|
91
|
-
},
|
|
92
|
-
method: "GET"
|
|
93
|
-
});
|
|
94
|
-
const locations = await response.json();
|
|
73
|
+
const { items: locations } = await this.catalog.getLocations(
|
|
74
|
+
{},
|
|
75
|
+
{
|
|
76
|
+
credentials: await this.getCredentials()
|
|
77
|
+
}
|
|
78
|
+
);
|
|
95
79
|
if (!Array.isArray(locations)) {
|
|
96
80
|
return { locations: [] };
|
|
97
81
|
}
|
|
98
|
-
const res = locations.filter(
|
|
99
|
-
(location) => location.data?.target && location.data?.type === "url"
|
|
100
|
-
).map((location) => {
|
|
82
|
+
const res = locations.filter((location) => location.target && location.type === "url").map((location) => {
|
|
101
83
|
return {
|
|
102
|
-
id: location.
|
|
103
|
-
target: location.
|
|
84
|
+
id: location.id,
|
|
85
|
+
target: location.target,
|
|
104
86
|
source: "location"
|
|
105
87
|
};
|
|
106
88
|
});
|
|
@@ -123,7 +105,7 @@ class CatalogHttpClient {
|
|
|
123
105
|
return { locations: filtered, totalCount: filtered.length };
|
|
124
106
|
}
|
|
125
107
|
async listCatalogUrlLocationEntitiesById(search, _pageNumber, _pageSize) {
|
|
126
|
-
const result = await this.
|
|
108
|
+
const result = await this.catalog.getEntities(
|
|
127
109
|
{
|
|
128
110
|
filter: {
|
|
129
111
|
kind: "Location"
|
|
@@ -135,7 +117,7 @@ class CatalogHttpClient {
|
|
|
135
117
|
order: { field: "metadata.name", order: "desc" }
|
|
136
118
|
},
|
|
137
119
|
{
|
|
138
|
-
|
|
120
|
+
credentials: await this.getCredentials()
|
|
139
121
|
}
|
|
140
122
|
);
|
|
141
123
|
const locations = result?.items ?? [];
|
|
@@ -159,14 +141,14 @@ class CatalogHttpClient {
|
|
|
159
141
|
*/
|
|
160
142
|
async verifyLocationExistence(repoCatalogUrl) {
|
|
161
143
|
try {
|
|
162
|
-
const result = await this.
|
|
144
|
+
const result = await this.catalog.addLocation(
|
|
163
145
|
{
|
|
164
146
|
type: "url",
|
|
165
147
|
target: repoCatalogUrl,
|
|
166
148
|
dryRun: true
|
|
167
149
|
},
|
|
168
150
|
{
|
|
169
|
-
|
|
151
|
+
credentials: await this.getCredentials()
|
|
170
152
|
}
|
|
171
153
|
);
|
|
172
154
|
return result.exists;
|
|
@@ -178,7 +160,7 @@ class CatalogHttpClient {
|
|
|
178
160
|
}
|
|
179
161
|
}
|
|
180
162
|
async hasEntityInCatalog(entityName) {
|
|
181
|
-
return this.
|
|
163
|
+
return this.catalog.queryEntities(
|
|
182
164
|
{
|
|
183
165
|
filter: {
|
|
184
166
|
"metadata.name": entityName
|
|
@@ -186,19 +168,19 @@ class CatalogHttpClient {
|
|
|
186
168
|
limit: 1
|
|
187
169
|
},
|
|
188
170
|
{
|
|
189
|
-
|
|
171
|
+
credentials: await this.getCredentials()
|
|
190
172
|
}
|
|
191
173
|
).then((resp) => resp.items?.length > 0);
|
|
192
174
|
}
|
|
193
175
|
async possiblyCreateLocation(repoCatalogUrl) {
|
|
194
176
|
try {
|
|
195
|
-
await this.
|
|
177
|
+
await this.catalog.addLocation(
|
|
196
178
|
{
|
|
197
179
|
type: "url",
|
|
198
180
|
target: repoCatalogUrl
|
|
199
181
|
},
|
|
200
182
|
{
|
|
201
|
-
|
|
183
|
+
credentials: await this.getCredentials()
|
|
202
184
|
}
|
|
203
185
|
);
|
|
204
186
|
} catch (error) {
|
|
@@ -209,18 +191,8 @@ class CatalogHttpClient {
|
|
|
209
191
|
}
|
|
210
192
|
async deleteCatalogLocationById(locationId) {
|
|
211
193
|
try {
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
)}/locations/${locationId}`;
|
|
215
|
-
await fetch__default.default(url, {
|
|
216
|
-
headers: {
|
|
217
|
-
Accept: "application/json",
|
|
218
|
-
Authorization: `Bearer ${await auth.getTokenForPlugin(
|
|
219
|
-
this.auth,
|
|
220
|
-
"catalog"
|
|
221
|
-
)}`
|
|
222
|
-
},
|
|
223
|
-
method: "DELETE"
|
|
194
|
+
await this.catalog.removeLocationById(locationId, {
|
|
195
|
+
credentials: await this.getCredentials()
|
|
224
196
|
});
|
|
225
197
|
} catch (error) {
|
|
226
198
|
loggingUtils.logErrorIfNeeded(
|
|
@@ -231,8 +203,8 @@ class CatalogHttpClient {
|
|
|
231
203
|
}
|
|
232
204
|
}
|
|
233
205
|
async deleteCatalogLocationEntityById(locationUid) {
|
|
234
|
-
await this.
|
|
235
|
-
|
|
206
|
+
await this.catalog.removeEntityByUid(locationUid, {
|
|
207
|
+
credentials: await this.getCredentials()
|
|
236
208
|
});
|
|
237
209
|
}
|
|
238
210
|
async findLocationEntitiesByRepoUrl(repoUrl, defaultBranch) {
|
|
@@ -241,7 +213,7 @@ class CatalogHttpClient {
|
|
|
241
213
|
);
|
|
242
214
|
}
|
|
243
215
|
async findLocationEntitiesByTargetUrl(targetUrl, limit) {
|
|
244
|
-
return this.
|
|
216
|
+
return this.catalog.queryEntities(
|
|
245
217
|
{
|
|
246
218
|
filter: [
|
|
247
219
|
{ kind: "Location", "spec.type": "url", "spec.target": targetUrl }
|
|
@@ -250,7 +222,7 @@ class CatalogHttpClient {
|
|
|
250
222
|
limit
|
|
251
223
|
},
|
|
252
224
|
{
|
|
253
|
-
|
|
225
|
+
credentials: await this.getCredentials()
|
|
254
226
|
}
|
|
255
227
|
).then((resp) => resp.items);
|
|
256
228
|
}
|
|
@@ -282,8 +254,8 @@ class CatalogHttpClient {
|
|
|
282
254
|
async refreshEntity(kind, name, namespace = "default") {
|
|
283
255
|
const entityRef = `${kind}:${namespace}/${name}`;
|
|
284
256
|
this.logger.debug(`Refreshing entityRef: ${entityRef}`);
|
|
285
|
-
await this.
|
|
286
|
-
|
|
257
|
+
await this.catalog.refreshEntity(entityRef, {
|
|
258
|
+
credentials: await this.getCredentials()
|
|
287
259
|
});
|
|
288
260
|
}
|
|
289
261
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"catalogHttpClient.cjs.js","sources":["../../src/catalog/catalogHttpClient.ts"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\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 type {\n AuthService,\n DiscoveryService,\n LoggerService,\n} from '@backstage/backend-plugin-api';\nimport type { CatalogApi } from '@backstage/catalog-client';\nimport type { LocationEntity } from '@backstage/catalog-model';\nimport type { Config } from '@backstage/config';\n\nimport fetch from 'node-fetch';\n\nimport { getTokenForPlugin, logErrorIfNeeded } from '../helpers';\nimport { filterLocations, getCatalogUrl } from './catalogUtils';\nimport { CatalogLocation } from './types';\n\nexport class CatalogHttpClient {\n private readonly logger: LoggerService;\n private readonly config: Config;\n private readonly discovery: DiscoveryService;\n private readonly auth: AuthService;\n private readonly catalogApi: CatalogApi;\n\n constructor(deps: {\n logger: LoggerService;\n config: Config;\n discovery: DiscoveryService;\n auth: AuthService;\n catalogApi: CatalogApi;\n }) {\n this.logger = deps.logger;\n this.config = deps.config;\n this.discovery = deps.discovery;\n this.auth = deps.auth;\n this.catalogApi = deps.catalogApi;\n }\n\n // Wrapper for https://backstage.io/docs/features/software-catalog/software-catalog-api/#post-analyze-location\n async analyzeLocation(repoUrl: string): Promise<any[]> {\n this.logger.debug(`Forwarding request to analyze location: ${repoUrl}`);\n const response = await fetch(\n `${await this.discovery.getBaseUrl('catalog')}/analyze-location`,\n {\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${await getTokenForPlugin(\n this.auth,\n 'catalog',\n )}`,\n },\n method: 'POST',\n body: JSON.stringify({\n location: {\n type: 'github',\n target: repoUrl,\n },\n }),\n },\n );\n return (await response.json()).generateEntities ?? [];\n }\n\n async listCatalogUrlLocations(\n search?: string,\n pageNumber?: number,\n pageSize?: number,\n ): Promise<{\n uniqueCatalogUrlLocations: Map<string, CatalogLocation>;\n totalCount?: number;\n }> {\n // byId order: config, locations, other\n const byId = await this.listCatalogUrlLocationsById(\n search,\n pageNumber,\n pageSize,\n );\n const result = new Map<string, CatalogLocation>();\n\n for (const l of byId.locations) {\n if (!result.has(l.target)) {\n result.set(l.target, l);\n }\n }\n return {\n uniqueCatalogUrlLocations: result,\n totalCount: byId.totalCount,\n };\n }\n\n async listCatalogUrlLocationsById(\n search?: string,\n pageNumber?: number,\n pageSize?: number,\n ): Promise<{\n locations: CatalogLocation[];\n totalCount?: number;\n }> {\n const result = await Promise.all([\n this.listCatalogUrlLocationsFromConfig(search),\n this.listCatalogUrlLocationsByIdFromLocationsEndpoint(search),\n this.listCatalogUrlLocationEntitiesById(search, pageNumber, pageSize),\n ]);\n const locations = result.flatMap(u => u.locations);\n // we might have duplicate elements here\n const totalCount = result\n .map(l => l.totalCount ?? 0)\n .reduce((accumulator, currentValue) => accumulator + currentValue, 0);\n return {\n locations,\n totalCount,\n };\n }\n\n async listCatalogUrlLocationsByIdFromLocationsEndpoint(\n search?: string,\n ): Promise<{\n locations: CatalogLocation[];\n totalCount?: number;\n }> {\n const url = `${await this.discovery.getBaseUrl('catalog')}/locations`;\n const response = await fetch(url, {\n headers: {\n Accept: 'application/json',\n Authorization: `Bearer ${await getTokenForPlugin(\n this.auth,\n 'catalog',\n )}`,\n },\n method: 'GET',\n });\n const locations = (await response.json()) as {\n data: { id: string; target: string; type: string };\n }[];\n if (!Array.isArray(locations)) {\n return { locations: [] };\n }\n const res = locations\n .filter(\n location => location.data?.target && location.data?.type === 'url',\n )\n .map(location => {\n return {\n id: location.data?.id,\n target: location.data.target,\n source: 'location',\n } as CatalogLocation;\n });\n const filtered = filterLocations(res, search);\n return { locations: filtered, totalCount: filtered.length };\n }\n\n listCatalogUrlLocationsFromConfig(search?: string): {\n locations: CatalogLocation[];\n totalCount?: number;\n } {\n const locationConfigs =\n this.config.getOptionalConfigArray('catalog.locations') ?? [];\n const res = locationConfigs\n .filter(\n location =>\n location.getOptionalString('target') &&\n location.getOptionalString('type') === 'url',\n )\n .map(location => {\n const target = location.getString('target');\n return {\n id: `app-config-location--${target}`,\n target,\n source: 'config',\n } as CatalogLocation;\n });\n const filtered = filterLocations(res, search);\n return { locations: filtered, totalCount: filtered.length };\n }\n\n async listCatalogUrlLocationEntitiesById(\n search?: string,\n _pageNumber?: number,\n _pageSize?: number,\n ): Promise<{\n locations: CatalogLocation[];\n totalCount?: number;\n }> {\n const result = await this.catalogApi.getEntities(\n {\n filter: {\n kind: 'Location',\n },\n // There is no query parameter to find entities with target URLs containing a string.\n // The existing filter does an exact matching. That's why we are retrieving this hard-coded high number of Locations.\n limit: 9999,\n offset: 0,\n order: { field: 'metadata.name', order: 'desc' },\n },\n {\n token: await getTokenForPlugin(this.auth, 'catalog'),\n },\n );\n const locations = (result?.items ?? []) as LocationEntity[];\n const res = locations\n .filter(\n location => location.spec?.target && location.spec?.type === 'url',\n )\n .map(location => {\n return {\n id: location.metadata.uid,\n target: location.spec.target!,\n source: 'integration',\n } as CatalogLocation;\n });\n const filtered = filterLocations(res, search);\n return { locations: filtered, totalCount: filtered.length };\n }\n\n /**\n * verifyLocationExistence checks for the existence of the Location target.\n * Under the hood, it attempts to read the target URL and will return false if the target could not be found\n * and even if there is already a Location row in the database.\n * @param repoCatalogUrl\n */\n async verifyLocationExistence(repoCatalogUrl: string): Promise<boolean> {\n try {\n const result = await this.catalogApi.addLocation(\n {\n type: 'url',\n target: repoCatalogUrl,\n dryRun: true,\n },\n {\n token: await getTokenForPlugin(this.auth, 'catalog'),\n },\n );\n // The `result.exists` field is only filled in dryRun mode\n return result.exists as boolean;\n } catch (error: any) {\n if (\n error.message?.includes('NotFoundError') ||\n error.body?.error?.message?.includes('NotFoundError')\n ) {\n return false;\n }\n throw error;\n }\n }\n\n async hasEntityInCatalog(entityName: string) {\n return this.catalogApi\n .queryEntities(\n {\n filter: {\n 'metadata.name': entityName,\n },\n limit: 1,\n },\n {\n token: await getTokenForPlugin(this.auth, 'catalog'),\n },\n )\n .then(resp => resp.items?.length > 0);\n }\n\n async possiblyCreateLocation(repoCatalogUrl: string) {\n try {\n await this.catalogApi.addLocation(\n {\n type: 'url',\n target: repoCatalogUrl,\n },\n {\n token: await getTokenForPlugin(this.auth, 'catalog'),\n },\n );\n } catch (error: any) {\n if (\n !(\n error.message?.includes('ConflictError') ||\n error.body?.error?.name?.includes('ConflictError')\n )\n ) {\n throw error;\n }\n // Location already exists, which is fine\n }\n }\n\n async deleteCatalogLocationById(locationId: string): Promise<void> {\n try {\n const url = `${await this.discovery.getBaseUrl(\n 'catalog',\n )}/locations/${locationId}`;\n await fetch(url, {\n headers: {\n Accept: 'application/json',\n Authorization: `Bearer ${await getTokenForPlugin(\n this.auth,\n 'catalog',\n )}`,\n },\n method: 'DELETE',\n });\n } catch (error: any) {\n logErrorIfNeeded(\n this.logger,\n `Could not delete location ${locationId}`,\n error,\n );\n }\n }\n\n async deleteCatalogLocationEntityById(locationUid: string): Promise<void> {\n await this.catalogApi.removeEntityByUid(locationUid, {\n token: await getTokenForPlugin(this.auth, 'catalog'),\n });\n }\n\n async findLocationEntitiesByRepoUrl(repoUrl: string, defaultBranch?: string) {\n return this.findLocationEntitiesByTargetUrl(\n getCatalogUrl(this.config, repoUrl, defaultBranch),\n );\n }\n\n async findLocationEntitiesByTargetUrl(targetUrl: string, limit?: number) {\n return this.catalogApi\n .queryEntities(\n {\n filter: [\n { kind: 'Location', 'spec.type': 'url', 'spec.target': targetUrl },\n ],\n fields: ['metadata.namespace', 'metadata.name', 'metadata.uid'],\n limit,\n },\n {\n token: await getTokenForPlugin(this.auth, 'catalog'),\n },\n )\n .then(resp => resp.items);\n }\n\n async refreshLocationByRepoUrl(repoUrl: string, defaultBranch?: string) {\n const promises: Promise<void>[] = [];\n this.findLocationEntitiesByRepoUrl(repoUrl, defaultBranch).then(\n entities => {\n const nbEntities = entities.length;\n if (nbEntities === 0) {\n this.logger.debug(`No Location Entity found for repo: ${repoUrl}`);\n return;\n }\n this.logger.debug(\n `Refreshing ${nbEntities} Location(s) for repo: ${repoUrl}`,\n );\n entities.forEach(ent =>\n promises.push(\n this.refreshEntity(\n 'location',\n ent.metadata.name,\n ent.metadata.namespace,\n ),\n ),\n );\n },\n );\n await Promise.all(promises);\n }\n\n async refreshEntity(\n kind: string,\n name: string,\n namespace: string = 'default',\n ) {\n const entityRef = `${kind}:${namespace}/${name}`;\n this.logger.debug(`Refreshing entityRef: ${entityRef}`);\n await this.catalogApi.refreshEntity(entityRef, {\n token: await getTokenForPlugin(this.auth, 'catalog'),\n });\n }\n}\n"],"names":["fetch","getTokenForPlugin","filterLocations","logErrorIfNeeded","getCatalogUrl"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"catalogHttpClient.cjs.js","sources":["../../src/catalog/catalogHttpClient.ts"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\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 type { AuthService, LoggerService } from '@backstage/backend-plugin-api';\nimport type { LocationEntity } from '@backstage/catalog-model';\nimport type { Config } from '@backstage/config';\nimport type { CatalogService } from '@backstage/plugin-catalog-node';\n\nimport { logErrorIfNeeded } from '../helpers';\nimport { filterLocations, getCatalogUrl } from './catalogUtils';\nimport { CatalogLocation } from './types';\n\nexport class CatalogHttpClient {\n private readonly logger: LoggerService;\n private readonly config: Config;\n private readonly auth: AuthService;\n private readonly catalog: CatalogService;\n\n constructor(deps: {\n logger: LoggerService;\n config: Config;\n auth: AuthService;\n catalog: CatalogService;\n }) {\n this.logger = deps.logger;\n this.config = deps.config;\n this.auth = deps.auth;\n this.catalog = deps.catalog;\n }\n\n private async getCredentials() {\n return this.auth.getOwnServiceCredentials();\n }\n\n // Wrapper for https://backstage.io/docs/features/software-catalog/software-catalog-api/#post-analyze-location\n async analyzeLocation(repoUrl: string): Promise<any[]> {\n this.logger.debug(`Forwarding request to analyze location: ${repoUrl}`);\n const response = await this.catalog.analyzeLocation(\n {\n location: {\n type: 'github',\n target: repoUrl,\n },\n },\n {\n credentials: await this.getCredentials(),\n },\n );\n return response.generateEntities ?? [];\n }\n\n async listCatalogUrlLocations(\n search?: string,\n pageNumber?: number,\n pageSize?: number,\n ): Promise<{\n uniqueCatalogUrlLocations: Map<string, CatalogLocation>;\n totalCount?: number;\n }> {\n // byId order: config, locations, other\n const byId = await this.listCatalogUrlLocationsById(\n search,\n pageNumber,\n pageSize,\n );\n const result = new Map<string, CatalogLocation>();\n\n for (const l of byId.locations) {\n if (!result.has(l.target)) {\n result.set(l.target, l);\n }\n }\n return {\n uniqueCatalogUrlLocations: result,\n totalCount: byId.totalCount,\n };\n }\n\n async listCatalogUrlLocationsById(\n search?: string,\n pageNumber?: number,\n pageSize?: number,\n ): Promise<{\n locations: CatalogLocation[];\n totalCount?: number;\n }> {\n const result = await Promise.all([\n this.listCatalogUrlLocationsFromConfig(search),\n this.listCatalogUrlLocationsByIdFromLocationsEndpoint(search),\n this.listCatalogUrlLocationEntitiesById(search, pageNumber, pageSize),\n ]);\n const locations = result.flatMap(u => u.locations);\n // we might have duplicate elements here\n const totalCount = result\n .map(l => l.totalCount ?? 0)\n .reduce((accumulator, currentValue) => accumulator + currentValue, 0);\n return {\n locations,\n totalCount,\n };\n }\n\n async listCatalogUrlLocationsByIdFromLocationsEndpoint(\n search?: string,\n ): Promise<{\n locations: CatalogLocation[];\n totalCount?: number;\n }> {\n const { items: locations } = await this.catalog.getLocations(\n {},\n {\n credentials: await this.getCredentials(),\n },\n );\n if (!Array.isArray(locations)) {\n return { locations: [] };\n }\n const res = locations\n .filter(location => location.target && location.type === 'url')\n .map(location => {\n return {\n id: location.id,\n target: location.target,\n source: 'location',\n } as CatalogLocation;\n });\n const filtered = filterLocations(res, search);\n return { locations: filtered, totalCount: filtered.length };\n }\n\n listCatalogUrlLocationsFromConfig(search?: string): {\n locations: CatalogLocation[];\n totalCount?: number;\n } {\n const locationConfigs =\n this.config.getOptionalConfigArray('catalog.locations') ?? [];\n const res = locationConfigs\n .filter(\n location =>\n location.getOptionalString('target') &&\n location.getOptionalString('type') === 'url',\n )\n .map(location => {\n const target = location.getString('target');\n return {\n id: `app-config-location--${target}`,\n target,\n source: 'config',\n } as CatalogLocation;\n });\n const filtered = filterLocations(res, search);\n return { locations: filtered, totalCount: filtered.length };\n }\n\n async listCatalogUrlLocationEntitiesById(\n search?: string,\n _pageNumber?: number,\n _pageSize?: number,\n ): Promise<{\n locations: CatalogLocation[];\n totalCount?: number;\n }> {\n const result = await this.catalog.getEntities(\n {\n filter: {\n kind: 'Location',\n },\n // There is no query parameter to find entities with target URLs containing a string.\n // The existing filter does an exact matching. That's why we are retrieving this hard-coded high number of Locations.\n limit: 9999,\n offset: 0,\n order: { field: 'metadata.name', order: 'desc' },\n },\n {\n credentials: await this.getCredentials(),\n },\n );\n const locations = (result?.items ?? []) as LocationEntity[];\n const res = locations\n .filter(\n location => location.spec?.target && location.spec?.type === 'url',\n )\n .map(location => {\n return {\n id: location.metadata.uid,\n target: location.spec.target!,\n source: 'integration',\n } as CatalogLocation;\n });\n const filtered = filterLocations(res, search);\n return { locations: filtered, totalCount: filtered.length };\n }\n\n /**\n * verifyLocationExistence checks for the existence of the Location target.\n * Under the hood, it attempts to read the target URL and will return false if the target could not be found\n * and even if there is already a Location row in the database.\n * @param repoCatalogUrl\n */\n async verifyLocationExistence(repoCatalogUrl: string): Promise<boolean> {\n try {\n const result = await this.catalog.addLocation(\n {\n type: 'url',\n target: repoCatalogUrl,\n dryRun: true,\n },\n {\n credentials: await this.getCredentials(),\n },\n );\n // The `result.exists` field is only filled in dryRun mode\n return result.exists as boolean;\n } catch (error: any) {\n if (\n error.message?.includes('NotFoundError') ||\n error.body?.error?.message?.includes('NotFoundError')\n ) {\n return false;\n }\n throw error;\n }\n }\n\n async hasEntityInCatalog(entityName: string) {\n return this.catalog\n .queryEntities(\n {\n filter: {\n 'metadata.name': entityName,\n },\n limit: 1,\n },\n {\n credentials: await this.getCredentials(),\n },\n )\n .then(resp => resp.items?.length > 0);\n }\n\n async possiblyCreateLocation(repoCatalogUrl: string) {\n try {\n await this.catalog.addLocation(\n {\n type: 'url',\n target: repoCatalogUrl,\n },\n {\n credentials: await this.getCredentials(),\n },\n );\n } catch (error: any) {\n if (\n !(\n error.message?.includes('ConflictError') ||\n error.body?.error?.name?.includes('ConflictError')\n )\n ) {\n throw error;\n }\n // Location already exists, which is fine\n }\n }\n\n async deleteCatalogLocationById(locationId: string): Promise<void> {\n try {\n await this.catalog.removeLocationById(locationId, {\n credentials: await this.getCredentials(),\n });\n } catch (error: any) {\n logErrorIfNeeded(\n this.logger,\n `Could not delete location ${locationId}`,\n error,\n );\n }\n }\n\n async deleteCatalogLocationEntityById(locationUid: string): Promise<void> {\n await this.catalog.removeEntityByUid(locationUid, {\n credentials: await this.getCredentials(),\n });\n }\n\n async findLocationEntitiesByRepoUrl(repoUrl: string, defaultBranch?: string) {\n return this.findLocationEntitiesByTargetUrl(\n getCatalogUrl(this.config, repoUrl, defaultBranch),\n );\n }\n\n async findLocationEntitiesByTargetUrl(targetUrl: string, limit?: number) {\n return this.catalog\n .queryEntities(\n {\n filter: [\n { kind: 'Location', 'spec.type': 'url', 'spec.target': targetUrl },\n ],\n fields: ['metadata.namespace', 'metadata.name', 'metadata.uid'],\n limit,\n },\n {\n credentials: await this.getCredentials(),\n },\n )\n .then(resp => resp.items);\n }\n\n async refreshLocationByRepoUrl(repoUrl: string, defaultBranch?: string) {\n const promises: Promise<void>[] = [];\n this.findLocationEntitiesByRepoUrl(repoUrl, defaultBranch).then(\n entities => {\n const nbEntities = entities.length;\n if (nbEntities === 0) {\n this.logger.debug(`No Location Entity found for repo: ${repoUrl}`);\n return;\n }\n this.logger.debug(\n `Refreshing ${nbEntities} Location(s) for repo: ${repoUrl}`,\n );\n entities.forEach(ent =>\n promises.push(\n this.refreshEntity(\n 'location',\n ent.metadata.name,\n ent.metadata.namespace,\n ),\n ),\n );\n },\n );\n await Promise.all(promises);\n }\n\n async refreshEntity(\n kind: string,\n name: string,\n namespace: string = 'default',\n ) {\n const entityRef = `${kind}:${namespace}/${name}`;\n this.logger.debug(`Refreshing entityRef: ${entityRef}`);\n await this.catalog.refreshEntity(entityRef, {\n credentials: await this.getCredentials(),\n });\n }\n}\n"],"names":["filterLocations","logErrorIfNeeded","getCatalogUrl"],"mappings":"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"}
|
package/dist/helpers/auth.cjs.js
CHANGED
|
@@ -28,14 +28,6 @@ async function permissionCheck(auditor, openApiOperationId, permissions, httpAut
|
|
|
28
28
|
throw err;
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
|
-
async function getTokenForPlugin(auth, targetPluginId) {
|
|
32
|
-
const resp = await auth.getPluginRequestToken({
|
|
33
|
-
onBehalfOf: await auth.getOwnServiceCredentials(),
|
|
34
|
-
targetPluginId
|
|
35
|
-
});
|
|
36
|
-
return resp.token;
|
|
37
|
-
}
|
|
38
31
|
|
|
39
|
-
exports.getTokenForPlugin = getTokenForPlugin;
|
|
40
32
|
exports.permissionCheck = permissionCheck;
|
|
41
33
|
//# sourceMappingURL=auth.cjs.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.cjs.js","sources":["../../src/helpers/auth.ts"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\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 type {\n AuditorService,\n
|
|
1
|
+
{"version":3,"file":"auth.cjs.js","sources":["../../src/helpers/auth.ts"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\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 type {\n AuditorService,\n HttpAuthService,\n PermissionsService,\n} from '@backstage/backend-plugin-api';\nimport { NotAllowedError } from '@backstage/errors';\nimport { AuthorizeResult } from '@backstage/plugin-permission-common';\n\nimport express from 'express';\n\nimport { bulkImportPermission } from '@red-hat-developer-hub/backstage-plugin-bulk-import-common';\n\nimport { auditCreateEvent } from './auditorUtils';\n\n/**\n * This will resolve to { result: AuthorizeResult.ALLOW } if the permission framework is disabled\n */\nexport async function permissionCheck(\n auditor: AuditorService,\n openApiOperationId: string | undefined,\n permissions: PermissionsService,\n httpAuth: HttpAuthService,\n req: express.Request,\n) {\n const decision = (\n await permissions.authorize(\n [\n {\n permission: bulkImportPermission,\n resourceRef: bulkImportPermission.resourceType,\n },\n ],\n {\n credentials: await httpAuth.credentials(req),\n },\n )\n )[0];\n\n if (decision.result === AuthorizeResult.DENY) {\n const err = new NotAllowedError('Unauthorized');\n const auditorEvent = await auditCreateEvent(\n auditor,\n openApiOperationId,\n req,\n );\n await auditorEvent.fail({ error: err, meta: { responseStatus: 403 } });\n throw err;\n }\n}\n"],"names":["bulkImportPermission","AuthorizeResult","NotAllowedError","auditCreateEvent"],"mappings":";;;;;;;AAiCA,eAAsB,eAAA,CACpB,OAAA,EACA,kBAAA,EACA,WAAA,EACA,UACA,GAAA,EACA;AACA,EAAA,MAAM,QAAA,GAAA,CACJ,MAAM,WAAA,CAAY,SAAA;AAAA,IAChB;AAAA,MACE;AAAA,QACE,UAAA,EAAYA,oDAAA;AAAA,QACZ,aAAaA,oDAAA,CAAqB;AAAA;AACpC,KACF;AAAA,IACA;AAAA,MACE,WAAA,EAAa,MAAM,QAAA,CAAS,WAAA,CAAY,GAAG;AAAA;AAC7C,KAEF,CAAC,CAAA;AAEH,EAAA,IAAI,QAAA,CAAS,MAAA,KAAWC,sCAAA,CAAgB,IAAA,EAAM;AAC5C,IAAA,MAAM,GAAA,GAAM,IAAIC,sBAAA,CAAgB,cAAc,CAAA;AAC9C,IAAA,MAAM,eAAe,MAAMC,6BAAA;AAAA,MACzB,OAAA;AAAA,MACA,kBAAA;AAAA,MACA;AAAA,KACF;AACA,IAAA,MAAM,YAAA,CAAa,IAAA,CAAK,EAAE,KAAA,EAAO,GAAA,EAAK,MAAM,EAAE,cAAA,EAAgB,GAAA,EAAI,EAAG,CAAA;AACrE,IAAA,MAAM,GAAA;AAAA,EACR;AACF;;;;"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as _backstage_backend_plugin_api from '@backstage/backend-plugin-api';
|
|
2
2
|
import { LoggerService, CacheService, DiscoveryService, HttpAuthService, AuthService, AuditorService, DatabaseService } from '@backstage/backend-plugin-api';
|
|
3
|
-
import { CatalogApi } from '@backstage/catalog-client';
|
|
4
3
|
import { Config } from '@backstage/config';
|
|
4
|
+
import { CatalogService } from '@backstage/plugin-catalog-node';
|
|
5
5
|
import { PermissionEvaluator } from '@backstage/plugin-permission-common';
|
|
6
6
|
import express from 'express';
|
|
7
7
|
|
|
@@ -23,7 +23,7 @@ interface RouterOptions {
|
|
|
23
23
|
discovery: DiscoveryService;
|
|
24
24
|
httpAuth: HttpAuthService;
|
|
25
25
|
auth: AuthService;
|
|
26
|
-
|
|
26
|
+
catalog: CatalogService;
|
|
27
27
|
auditor: AuditorService;
|
|
28
28
|
database: DatabaseService;
|
|
29
29
|
}
|
package/dist/plugin.cjs.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var backendPluginApi = require('@backstage/backend-plugin-api');
|
|
4
|
-
var
|
|
4
|
+
var pluginCatalogNode = require('@backstage/plugin-catalog-node');
|
|
5
|
+
var backstagePluginBulkImportCommon = require('@red-hat-developer-hub/backstage-plugin-bulk-import-common');
|
|
5
6
|
var router = require('./service/router.cjs.js');
|
|
6
7
|
|
|
7
8
|
const bulkImportPlugin = backendPluginApi.createBackendPlugin({
|
|
@@ -15,9 +16,10 @@ const bulkImportPlugin = backendPluginApi.createBackendPlugin({
|
|
|
15
16
|
cache: backendPluginApi.coreServices.cache,
|
|
16
17
|
discovery: backendPluginApi.coreServices.discovery,
|
|
17
18
|
permissions: backendPluginApi.coreServices.permissions,
|
|
19
|
+
permissionsRegistry: backendPluginApi.coreServices.permissionsRegistry,
|
|
18
20
|
httpAuth: backendPluginApi.coreServices.httpAuth,
|
|
19
21
|
auth: backendPluginApi.coreServices.auth,
|
|
20
|
-
|
|
22
|
+
catalog: pluginCatalogNode.catalogServiceRef,
|
|
21
23
|
auditor: backendPluginApi.coreServices.auditor,
|
|
22
24
|
database: backendPluginApi.coreServices.database
|
|
23
25
|
},
|
|
@@ -28,12 +30,14 @@ const bulkImportPlugin = backendPluginApi.createBackendPlugin({
|
|
|
28
30
|
cache,
|
|
29
31
|
discovery,
|
|
30
32
|
permissions,
|
|
33
|
+
permissionsRegistry,
|
|
31
34
|
httpAuth,
|
|
32
35
|
auth,
|
|
33
|
-
|
|
36
|
+
catalog,
|
|
34
37
|
auditor,
|
|
35
38
|
database
|
|
36
39
|
}) {
|
|
40
|
+
permissionsRegistry.addPermissions([backstagePluginBulkImportCommon.bulkImportPermission]);
|
|
37
41
|
const router$1 = await router.createRouter({
|
|
38
42
|
config,
|
|
39
43
|
cache,
|
|
@@ -42,7 +46,7 @@ const bulkImportPlugin = backendPluginApi.createBackendPlugin({
|
|
|
42
46
|
logger,
|
|
43
47
|
httpAuth,
|
|
44
48
|
auth,
|
|
45
|
-
|
|
49
|
+
catalog,
|
|
46
50
|
auditor,
|
|
47
51
|
database
|
|
48
52
|
});
|
package/dist/plugin.cjs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.cjs.js","sources":["../src/plugin.ts"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\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 {\n coreServices,\n createBackendPlugin,\n} from '@backstage/backend-plugin-api';\nimport { catalogServiceRef } from '@backstage/plugin-catalog-node/
|
|
1
|
+
{"version":3,"file":"plugin.cjs.js","sources":["../src/plugin.ts"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\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 {\n coreServices,\n createBackendPlugin,\n} from '@backstage/backend-plugin-api';\nimport { catalogServiceRef } from '@backstage/plugin-catalog-node';\n\nimport { bulkImportPermission } from '@red-hat-developer-hub/backstage-plugin-bulk-import-common';\n\nimport { createRouter } from './service/router';\n\n/**\n * The bulk-import backend plugin.\n * @public\n */\nexport const bulkImportPlugin = createBackendPlugin({\n pluginId: 'bulk-import',\n register(env) {\n env.registerInit({\n deps: {\n logger: coreServices.logger,\n config: coreServices.rootConfig,\n http: coreServices.httpRouter,\n cache: coreServices.cache,\n discovery: coreServices.discovery,\n permissions: coreServices.permissions,\n permissionsRegistry: coreServices.permissionsRegistry,\n httpAuth: coreServices.httpAuth,\n auth: coreServices.auth,\n catalog: catalogServiceRef,\n auditor: coreServices.auditor,\n database: coreServices.database,\n },\n async init({\n config,\n logger,\n http,\n cache,\n discovery,\n permissions,\n permissionsRegistry,\n httpAuth,\n auth,\n catalog,\n auditor,\n database,\n }) {\n permissionsRegistry.addPermissions([bulkImportPermission]);\n\n const router = await createRouter({\n config,\n cache,\n discovery,\n permissions,\n logger,\n httpAuth,\n auth,\n catalog,\n auditor,\n database,\n });\n http.use(router);\n http.addAuthPolicy({\n path: '/ping',\n allow: 'unauthenticated',\n });\n },\n });\n },\n});\n"],"names":["createBackendPlugin","coreServices","catalogServiceRef","bulkImportPermission","router","createRouter"],"mappings":";;;;;;;AA8BO,MAAM,mBAAmBA,oCAAA,CAAoB;AAAA,EAClD,QAAA,EAAU,aAAA;AAAA,EACV,SAAS,GAAA,EAAK;AACZ,IAAA,GAAA,CAAI,YAAA,CAAa;AAAA,MACf,IAAA,EAAM;AAAA,QACJ,QAAQC,6BAAA,CAAa,MAAA;AAAA,QACrB,QAAQA,6BAAA,CAAa,UAAA;AAAA,QACrB,MAAMA,6BAAA,CAAa,UAAA;AAAA,QACnB,OAAOA,6BAAA,CAAa,KAAA;AAAA,QACpB,WAAWA,6BAAA,CAAa,SAAA;AAAA,QACxB,aAAaA,6BAAA,CAAa,WAAA;AAAA,QAC1B,qBAAqBA,6BAAA,CAAa,mBAAA;AAAA,QAClC,UAAUA,6BAAA,CAAa,QAAA;AAAA,QACvB,MAAMA,6BAAA,CAAa,IAAA;AAAA,QACnB,OAAA,EAASC,mCAAA;AAAA,QACT,SAASD,6BAAA,CAAa,OAAA;AAAA,QACtB,UAAUA,6BAAA,CAAa;AAAA,OACzB;AAAA,MACA,MAAM,IAAA,CAAK;AAAA,QACT,MAAA;AAAA,QACA,MAAA;AAAA,QACA,IAAA;AAAA,QACA,KAAA;AAAA,QACA,SAAA;AAAA,QACA,WAAA;AAAA,QACA,mBAAA;AAAA,QACA,QAAA;AAAA,QACA,IAAA;AAAA,QACA,OAAA;AAAA,QACA,OAAA;AAAA,QACA;AAAA,OACF,EAAG;AACD,QAAA,mBAAA,CAAoB,cAAA,CAAe,CAACE,oDAAoB,CAAC,CAAA;AAEzD,QAAA,MAAMC,QAAA,GAAS,MAAMC,mBAAA,CAAa;AAAA,UAChC,MAAA;AAAA,UACA,KAAA;AAAA,UACA,SAAA;AAAA,UACA,WAAA;AAAA,UACA,MAAA;AAAA,UACA,QAAA;AAAA,UACA,IAAA;AAAA,UACA,OAAA;AAAA,UACA,OAAA;AAAA,UACA;AAAA,SACD,CAAA;AACD,QAAA,IAAA,CAAK,IAAID,QAAM,CAAA;AACf,QAAA,IAAA,CAAK,aAAA,CAAc;AAAA,UACjB,IAAA,EAAM,OAAA;AAAA,UACN,KAAA,EAAO;AAAA,SACR,CAAA;AAAA,MACH;AAAA,KACD,CAAA;AAAA,EACH;AACF,CAAC;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bulkImports.cjs.js","sources":["../../../../src/service/handlers/import/bulkImports.ts"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\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 type {\n AuthService,\n DiscoveryService,\n LoggerService,\n} from '@backstage/backend-plugin-api';\nimport type { CatalogApi } from '@backstage/catalog-client';\nimport type { Config } from '@backstage/config';\nimport { NotFoundError } from '@backstage/errors';\n\nimport gitUrlParse from 'git-url-parse';\n\nimport {\n Configuration,\n DefaultApi,\n} from '@red-hat-developer-hub/backstage-plugin-orchestrator-common';\n\nimport { CatalogHttpClient } from '../../../catalog/catalogHttpClient';\nimport type { CatalogInfoGenerator } from '../../../catalog/catalogInfoGenerator';\nimport {\n getCatalogFilename,\n getCatalogUrl,\n} from '../../../catalog/catalogUtils';\nimport {\n OrchestratorWorkflow,\n OrchestratorWorkflowDao,\n RepositoryDao,\n RepositoryName,\n ScaffolderTaskDao,\n TaskLocationsDao,\n} from '../../../database/repositoryDao';\nimport type { Components, Paths } from '../../../generated/openapi';\nimport type { GithubApiService } from '../../../github';\nimport { GitlabApiService } from '../../../gitlab';\nimport {\n getNestedValue,\n logErrorIfNeeded,\n paginateArray,\n parseGitURLForApprovalTool,\n} from '../../../helpers';\nimport { GitApiService } from '../../../scm/GitApiService';\nimport {\n DefaultPageNumber,\n DefaultPageSize,\n DefaultSortColumn,\n DefaultSortOrder,\n type HandlerResponse,\n} from '../handlers';\n\ntype CreateImportDryRunStatus =\n | 'CATALOG_ENTITY_CONFLICT'\n | 'CATALOG_INFO_FILE_EXISTS_IN_REPO'\n | 'CODEOWNERS_FILE_NOT_FOUND_IN_REPO'\n | 'REPO_EMPTY';\n\ntype FindAllImportsResponse =\n | Components.Schemas.Import[]\n | Components.Schemas.ImportJobListV2;\n\nexport function sortImports(\n imports: Components.Schemas.Import[],\n sortColumn: Components.Parameters.SortColumnQueryParam = DefaultSortColumn,\n sortOrder: Components.Parameters.SortOrderQueryParam = DefaultSortOrder,\n) {\n imports.sort((a, b) => {\n const value1 = getNestedValue(a, sortColumn);\n const value2 = getNestedValue(b, sortColumn);\n // Handle cases where values are undefined\n if (value1 === undefined && value2 === undefined) return 0;\n if (value1 === undefined) return sortOrder === 'asc' ? -1 : 1;\n if (value2 === undefined) return sortOrder === 'asc' ? 1 : -1;\n\n if (sortColumn === 'lastUpdate') {\n const date1 = new Date(value1); // Convert string to Date object\n const date2 = new Date(value2); // Convert string to Date object\n // Compare dates\n return sortOrder === 'asc'\n ? date2.getTime() - date1.getTime()\n : date1.getTime() - date2.getTime();\n }\n // Compare values based on sort order\n return sortOrder === 'asc'\n ? value1.localeCompare(value2)\n : value2.localeCompare(value1);\n });\n}\n\nexport async function findAllImports(\n deps: {\n logger: LoggerService;\n config: Config;\n gitlabApiService: GitlabApiService;\n githubApiService: GithubApiService;\n catalogHttpClient: CatalogHttpClient;\n },\n requestHeaders?: {\n apiVersion?: Paths.FindAllImports.Parameters.ApiVersion;\n },\n queryParams?: {\n search?: string;\n pageNumber?: number;\n pageSize?: number;\n sortColumn?: Components.Parameters.SortColumnQueryParam;\n sortOrder?: Components.Parameters.SortOrderQueryParam;\n },\n): Promise<HandlerResponse<FindAllImportsResponse>> {\n const apiVersion = requestHeaders?.apiVersion ?? 'v1';\n const search = queryParams?.search;\n const pageNumber = queryParams?.pageNumber ?? DefaultPageNumber;\n const pageSize = queryParams?.pageSize ?? DefaultPageSize;\n const sortColumn = queryParams?.sortColumn ?? DefaultSortColumn;\n const sortOrder = queryParams?.sortOrder ?? DefaultSortOrder;\n\n const catalogFilename = getCatalogFilename(deps.config);\n\n const allLocations = (\n await deps.catalogHttpClient.listCatalogUrlLocations(\n search,\n pageNumber,\n pageSize,\n )\n ).uniqueCatalogUrlLocations;\n\n // resolve default branches for each unique repo URL from GH,\n // because we cannot easily determine that from the location target URL.\n // It can be 'main' or something more convoluted like 'our/awesome/main'.\n const defaultBranchByRepoUrl = await resolveReposDefaultBranches(\n deps.logger,\n deps.gitlabApiService,\n deps.githubApiService,\n allLocations.keys(),\n catalogFilename,\n );\n\n // filter out locations that do not match what we are expecting, i.e.:\n // an URL to a catalog-info YAML file at the root of the repo\n const importCandidates = findImportCandidates(\n allLocations.keys(),\n defaultBranchByRepoUrl,\n catalogFilename,\n );\n\n // Keep only repos that are accessible from the configured GH/GL integrations\n const importsReachableFromGHIntegrations =\n await deps.githubApiService.filterLocationsAccessibleFromIntegrations(\n importCandidates.filter(val => {\n return parseGitURLForApprovalTool(val) === 'GIT';\n }),\n );\n\n const importsReachableFromGLIntegrations =\n await deps.gitlabApiService.filterLocationsAccessibleFromIntegrations(\n importCandidates.filter(val => {\n return parseGitURLForApprovalTool(val) === 'GITLAB';\n }),\n );\n\n // Merge the two lists together and map the appropriate approvalTool\n const mergedReachbleFromIntegrations = importsReachableFromGHIntegrations\n .map(val => {\n return {\n loc: val,\n approvalTool: 'GIT',\n };\n })\n .concat(\n importsReachableFromGLIntegrations.map(val => {\n return {\n loc: val,\n approvalTool: 'GITLAB',\n };\n }),\n );\n\n const repoUrlToLocation = new Map<string, string>();\n\n // now fetch the import statuses in different promises\n const importStatusPromises: Promise<\n HandlerResponse<Components.Schemas.Import>\n >[] = [];\n for (const imports of mergedReachbleFromIntegrations) {\n const repoUrl = repoUrlFromLocation(imports.loc);\n if (!repoUrl) {\n continue;\n }\n repoUrlToLocation.set(repoUrl, imports.loc);\n\n importStatusPromises.push(\n findImportStatusByRepo(\n {\n logger: deps.logger,\n config: deps.config,\n gitApiService:\n imports.approvalTool === 'GITLAB'\n ? deps.gitlabApiService\n : deps.githubApiService,\n catalogHttpClient: deps.catalogHttpClient,\n approvalTool: imports.approvalTool,\n },\n repoUrl,\n defaultBranchByRepoUrl.get(repoUrl),\n false,\n ),\n );\n }\n\n const result = await Promise.all(importStatusPromises);\n const imports = result\n .filter(res => res.responseBody)\n .map(res => res.responseBody!)\n .map(res => {\n const key = res?.repository?.url;\n const location = key ? repoUrlToLocation.get(key) : undefined;\n return {\n ...res,\n source: location ? allLocations.get(location)?.source : undefined,\n };\n });\n\n // sorting the output to make it deterministic and easy to navigate in the UI\n\n sortImports(imports, sortColumn, sortOrder);\n const paginated = paginateArray(imports, pageNumber, pageSize);\n if (apiVersion === 'v1') {\n return {\n statusCode: 200,\n responseBody: paginated.result,\n };\n }\n return {\n statusCode: 200,\n responseBody: {\n imports: paginated.result,\n totalCount: paginated.totalCount,\n page: pageNumber,\n size: pageSize,\n },\n };\n}\n\nasync function resolveReposDefaultBranches(\n logger: LoggerService,\n gitlabApiService: GitlabApiService,\n githubApiService: GithubApiService,\n allLocations: Iterable<string>,\n catalogFilename: string,\n) {\n const defaultBranchByRepoUrlPromises: Promise<{\n repoUrl: string;\n defaultBranch?: string;\n }>[] = [];\n for (const loc of allLocations) {\n // loc has the following format: https://github.com/<org>/<repo>/blob/<default-branch>/catalog-info.yaml\n // but it can have a more convoluted format like 'https://github.com/redhat-developer/rhdh-plugins/blob/main/plugins/scaffolder-annotator-action/examples/templates/01-scaffolder-template.yaml'\n // if registered manually from the 'Register existing component' feature in Backstage.\n if (!loc.endsWith(catalogFilename)) {\n logger.debug(\n `Ignored location ${loc} because it does not point to a file named ${catalogFilename}`,\n );\n continue;\n }\n const repoUrl = repoUrlFromLocation(loc);\n if (!repoUrl) {\n continue;\n }\n // Have to do this for Both the gitlab/github, possibly a better way?\n // Should probably parse the URL to figure out which to use?\n defaultBranchByRepoUrlPromises.push(\n (parseGitURLForApprovalTool(repoUrl) === 'GITLAB'\n ? gitlabApiService\n : githubApiService\n )\n .getRepositoryFromIntegrations(repoUrl)\n .then(resp => {\n return { repoUrl, defaultBranch: resp?.repository?.default_branch };\n })\n .catch((err: any) => {\n logErrorIfNeeded(\n logger,\n `Ignored repo ${repoUrl} due to an error while fetching details from GitHub`,\n err,\n );\n return {\n repoUrl,\n defaultBranch: undefined,\n };\n }),\n );\n }\n const defaultBranchesResponses = await Promise.all(\n defaultBranchByRepoUrlPromises,\n );\n return new Map(\n defaultBranchesResponses\n .flat()\n .filter(r => r.defaultBranch)\n .map(r => [r.repoUrl, r.defaultBranch!]),\n );\n}\n\nfunction repoUrlFromLocation(loc: string) {\n const split = loc.split('/blob/');\n if (split.length < 2) {\n return undefined;\n }\n return split[0];\n}\n\nfunction findImportCandidates(\n allLocations: Iterable<string>,\n defaultBranchByRepoUrl: Map<string, string>,\n catalogFilename: string,\n) {\n const filteredLocations: string[] = [];\n for (const loc of allLocations) {\n const repoUrl = repoUrlFromLocation(loc);\n if (!repoUrl) {\n continue;\n }\n\n const defaultBranch = defaultBranchByRepoUrl.get(repoUrl);\n if (!defaultBranch) {\n continue;\n }\n if (loc !== `${repoUrl}/blob/${defaultBranch}/${catalogFilename}`) {\n // Because users can use the \"Register existing component\" workflow to register a Location\n // using any file path in the repo, we consider a repository as an Import Location only\n // if it is at the root of the repository, because that is what the import PR ultimately does.\n continue;\n }\n filteredLocations.push(loc);\n }\n return filteredLocations;\n}\n\nasync function createPR(\n gitApiService: GitApiService,\n logger: LoggerService,\n req: Components.Schemas.ImportRequest,\n gitUrl: gitUrlParse.GitUrl,\n catalogInfoGenerator: CatalogInfoGenerator,\n config: Config,\n) {\n const appTitle =\n config.getOptionalString('app.title') ?? 'Red Hat Developer Hub';\n const appBaseUrl = config.getString('app.baseUrl');\n const catalogFileName = getCatalogFilename(config);\n return await gitApiService.submitPrToRepo(logger, {\n repoUrl: req.repository.url,\n gitUrl: gitUrl,\n defaultBranch: req.repository.defaultBranch,\n catalogInfoContent:\n req.catalogInfoContent ??\n (await catalogInfoGenerator.generateDefaultCatalogInfoContent(\n req.repository.url,\n )),\n prTitle:\n req[req.approvalTool === 'GITLAB' ? 'gitlab' : 'github']?.pullRequest\n ?.title ?? `Add ${catalogFileName}`,\n prBody:\n req[req.approvalTool === 'GITLAB' ? 'gitlab' : 'github']?.pullRequest\n ?.body ??\n `\nThis pull request adds a **Backstage entity metadata file** to this repository so that the component can be added to a Backstage application.\n\nAfter this pull request is merged, the component will become available in the [${appTitle} software catalog](${appBaseUrl}).\n\nFor more information, read an [overview of the Backstage software catalog](https://backstage.io/docs/features/software-catalog/).\n`,\n });\n}\n\nasync function handleAddedReposFromCreateImportJobs(\n deps: {\n logger: LoggerService;\n config: Config;\n auth: AuthService;\n catalogApi: CatalogApi;\n gitlabApiService: GitlabApiService;\n githubApiService: GithubApiService;\n catalogInfoGenerator: CatalogInfoGenerator;\n catalogHttpClient: CatalogHttpClient;\n },\n importRequests: Components.Schemas.ImportRequest[],\n) {\n const result: Components.Schemas.Import[] = [];\n\n for (const req of importRequests) {\n // Check if repo is already imported\n const repoCatalogUrl = getCatalogUrl(\n deps.config,\n req.repository.url,\n req.repository.defaultBranch,\n );\n const hasLocation =\n await deps.catalogHttpClient.verifyLocationExistence(repoCatalogUrl);\n if (!hasLocation) {\n continue;\n }\n const gitApiService =\n req.approvalTool === 'GITLAB'\n ? deps.gitlabApiService\n : deps.githubApiService;\n const hasCatalogInfoFileInRepo = await gitApiService.hasFileInRepo({\n repoUrl: req.repository.url,\n defaultBranch: req.repository.defaultBranch,\n fileName: getCatalogFilename(deps.config),\n });\n if (!hasCatalogInfoFileInRepo) {\n continue;\n }\n\n const ghRepo = await gitApiService.getRepositoryFromIntegrations(\n req.repository.url,\n );\n\n // Force a refresh of the Location, so that the entities from the catalog-info.yaml can show up quickly (not guaranteed however).\n await deps.catalogHttpClient.refreshLocationByRepoUrl(\n req.repository.url,\n req.repository.defaultBranch,\n );\n\n const gitUrl = gitUrlParse(req.repository.url);\n result.push({\n status: 'ADDED',\n lastUpdate: ghRepo?.repository?.updated_at ?? undefined,\n repository: {\n url: req.repository.url,\n name: gitUrl.name,\n organization: gitUrl.organization,\n },\n });\n }\n return result;\n}\n\nasync function handlePrCreationRequest(\n deps: {\n logger: LoggerService;\n config: Config;\n auth: AuthService;\n catalogApi: CatalogApi;\n gitlabApiService: GitlabApiService;\n githubApiService: GithubApiService;\n catalogInfoGenerator: CatalogInfoGenerator;\n catalogHttpClient: CatalogHttpClient;\n },\n req: Components.Schemas.ImportRequest,\n gitUrl: gitUrlParse.GitUrl,\n): Promise<Components.Schemas.Import> {\n const repoCatalogUrl = getCatalogUrl(\n deps.config,\n req.repository.url,\n req.repository.defaultBranch,\n );\n const gitApiService =\n req.approvalTool === 'GITLAB'\n ? deps.gitlabApiService\n : deps.githubApiService;\n const prToRepo = await createPR(\n gitApiService,\n deps.logger,\n req,\n gitUrl,\n deps.catalogInfoGenerator,\n deps.config,\n );\n if (prToRepo.errors && prToRepo.errors.length > 0) {\n return {\n errors: prToRepo.errors,\n status: 'PR_ERROR',\n repository: req.repository,\n };\n }\n if (prToRepo.prUrl) {\n deps.logger.debug(`Created new PR from request: ${prToRepo.prUrl}`);\n }\n\n // Create Location\n await deps.catalogHttpClient.possiblyCreateLocation(repoCatalogUrl);\n\n if (prToRepo.hasChanges === false) {\n deps.logger.debug(\n `No bulk import PR created on ${req.repository.url} since its default branch (${req.repository.defaultBranch}) already contains a catalog-info file`,\n );\n\n // Force a refresh of the Location, so that the entities from the catalog-info.yaml can show up quickly (not guaranteed however).\n await deps.catalogHttpClient.refreshLocationByRepoUrl(\n req.repository.url,\n req.repository.defaultBranch,\n );\n return {\n status: 'ADDED',\n lastUpdate: prToRepo.lastUpdate,\n repository: {\n url: req.repository.url,\n name: gitUrl.name,\n organization: gitUrl.organization,\n },\n };\n }\n\n return {\n approvalTool: req.approvalTool ?? 'GIT',\n errors: prToRepo.errors,\n status: 'WAIT_PR_APPROVAL',\n lastUpdate: prToRepo.lastUpdate,\n repository: {\n url: req.repository.url,\n name: gitUrl.name,\n organization: gitUrl.organization,\n },\n [req.approvalTool === 'GITLAB' ? 'gitlab' : 'github']: {\n pullRequest: {\n url: prToRepo.prUrl,\n number: prToRepo.prNumber,\n },\n },\n };\n}\n\nexport async function createImportJobs(\n deps: {\n logger: LoggerService;\n config: Config;\n auth: AuthService;\n catalogApi: CatalogApi;\n gitlabApiService: GitlabApiService;\n githubApiService: GithubApiService;\n catalogInfoGenerator: CatalogInfoGenerator;\n catalogHttpClient: CatalogHttpClient;\n },\n reqParams: {\n importRequests: Paths.CreateImportJobs.RequestBody;\n dryRun?: boolean;\n },\n): Promise<HandlerResponse<Components.Schemas.Import[]>> {\n const dryRun = reqParams.dryRun ?? false;\n const importRequests = reqParams.importRequests;\n deps.logger.debug(\n `Handling request to import ${importRequests?.length} repo(s) (dryRun=${dryRun})..`,\n );\n\n if (importRequests.length === 0) {\n deps.logger.debug('Missing import requests from request body');\n return {\n statusCode: 400,\n responseBody: [],\n };\n }\n\n if (dryRun) {\n return {\n statusCode: 202,\n responseBody: await dryRunCreateImportJobs(deps, importRequests),\n };\n }\n\n const result: Components.Schemas.Import[] = [];\n\n const addedRepos = await handleAddedReposFromCreateImportJobs(\n deps,\n importRequests,\n );\n result.push(...addedRepos);\n const addedReposMap = new Map(\n addedRepos.map(res => [res.repository?.url, res]),\n );\n const remainingRequests = importRequests.filter(\n req => !addedReposMap.has(req.repository.url),\n );\n\n for (const req of remainingRequests) {\n const gitUrl = gitUrlParse(req.repository.url);\n\n // Create PR\n try {\n result.push(await handlePrCreationRequest(deps, req, gitUrl));\n } catch (error: any) {\n result.push({\n errors: [error.message],\n status: 'PR_ERROR',\n repository: {\n url: req.repository.url,\n name: gitUrl.name,\n organization: gitUrl.organization,\n },\n } as Components.Schemas.Import);\n }\n }\n\n sortImports(result);\n\n return {\n statusCode: 202,\n responseBody: result,\n };\n}\n\nasync function dryRunCreateImportJobs(\n deps: {\n logger: LoggerService;\n config: Config;\n auth: AuthService;\n catalogApi: CatalogApi;\n gitlabApiService: GitlabApiService;\n githubApiService: GithubApiService;\n catalogInfoGenerator: CatalogInfoGenerator;\n catalogHttpClient: CatalogHttpClient;\n },\n importRequests: Paths.CreateImportJobs.RequestBody,\n) {\n const result: Components.Schemas.Import[] = [];\n for (const req of importRequests) {\n const gitUrl = gitUrlParse(req.repository.url);\n\n const dryRunChecks = await performDryRunChecks(deps, req);\n if (dryRunChecks.errors?.length > 0) {\n deps.logger.warn(\n `Errors while performing dry-run checks: ${dryRunChecks.errors}`,\n );\n }\n result.push({\n errors: dryRunChecks.dryRunStatuses,\n catalogEntityName: req.catalogEntityName,\n repository: {\n url: req.repository.url,\n name: gitUrl.name,\n organization: gitUrl.organization,\n },\n });\n }\n return result;\n}\n\nasync function performDryRunChecks(\n deps: {\n logger: LoggerService;\n auth: AuthService;\n catalogApi: CatalogApi;\n config: Config;\n gitlabApiService: GitlabApiService;\n githubApiService: GithubApiService;\n catalogHttpClient: CatalogHttpClient;\n },\n req: Components.Schemas.ImportRequest,\n): Promise<{ dryRunStatuses: CreateImportDryRunStatus[]; errors: string[] }> {\n const checkCatalog = async (\n catalogEntityName: string,\n ): Promise<{\n dryRunStatuses?: CreateImportDryRunStatus[];\n errors?: string[];\n }> => {\n const hasEntity =\n await deps.catalogHttpClient.hasEntityInCatalog(catalogEntityName);\n if (hasEntity) {\n return { dryRunStatuses: ['CATALOG_ENTITY_CONFLICT'] };\n }\n return {};\n };\n\n const gitApiService =\n req.approvalTool === 'GITLAB'\n ? deps.gitlabApiService\n : deps.githubApiService;\n const checkEmptyRepo = async (): Promise<{\n dryRunStatuses?: CreateImportDryRunStatus[];\n errors?: string[];\n }> => {\n const empty = await gitApiService.isRepoEmpty({\n repoUrl: req.repository.url,\n });\n if (empty) {\n return {\n dryRunStatuses: ['REPO_EMPTY'],\n };\n }\n return {};\n };\n\n const checkCatalogInfoPresenceInRepo = async (): Promise<{\n dryRunStatuses?: CreateImportDryRunStatus[];\n errors?: string[];\n }> => {\n const exists = await gitApiService.hasFileInRepo({\n repoUrl: req.repository.url,\n defaultBranch: req.repository.defaultBranch,\n fileName: getCatalogFilename(deps.config),\n });\n if (exists) {\n return {\n dryRunStatuses: ['CATALOG_INFO_FILE_EXISTS_IN_REPO'],\n };\n }\n return {};\n };\n\n const checkCodeOwnersFileInRepo = async (): Promise<{\n dryRunStatuses?: CreateImportDryRunStatus[];\n errors?: string[];\n }> => {\n const gitDirLocation =\n req.approvalTool === 'GITLAB' ? '.gitlab' : '.github';\n const exists = await gitApiService.hasFileInRepo({\n repoUrl: req.repository.url,\n defaultBranch: req.repository.defaultBranch,\n fileName: `${gitDirLocation}/CODEOWNERS`,\n });\n if (!exists) {\n return {\n dryRunStatuses: ['CODEOWNERS_FILE_NOT_FOUND_IN_REPO'],\n };\n }\n return {};\n };\n\n const dryRunStatuses: CreateImportDryRunStatus[] = [];\n const errors: string[] = [];\n const allChecksFn = [checkEmptyRepo(), checkCatalogInfoPresenceInRepo()];\n if (req.catalogEntityName?.trim()) {\n allChecksFn.push(checkCatalog(req.catalogEntityName));\n }\n if (req.codeOwnersFileAsEntityOwner) {\n allChecksFn.push(checkCodeOwnersFileInRepo());\n }\n const allChecks = await Promise.all(allChecksFn);\n allChecks.flat().forEach(res => {\n if (res.dryRunStatuses) {\n dryRunStatuses.push(...res.dryRunStatuses);\n }\n if (res.errors) {\n errors.push(...res.errors);\n }\n });\n\n dryRunStatuses.sort((a, b) => a.localeCompare(b));\n\n return {\n dryRunStatuses,\n errors,\n };\n}\n\nexport async function findImportStatusByRepo(\n deps: {\n logger: LoggerService;\n config: Config;\n gitApiService: GitlabApiService | GithubApiService;\n catalogHttpClient: CatalogHttpClient;\n approvalTool: string | undefined;\n },\n repoUrl: string,\n defaultBranch?: string,\n includeCatalogInfoContent?: boolean,\n): Promise<HandlerResponse<Components.Schemas.Import>> {\n deps.logger.debug(`Getting bulk import job status for ${repoUrl}..`);\n\n const gitUrl = gitUrlParse(repoUrl);\n\n const errors: string[] = [];\n const result = {\n id: repoUrl,\n repository: {\n url: repoUrl,\n name: gitUrl.name,\n organization: gitUrl.organization,\n id: `${gitUrl.organization}/${gitUrl.name}`,\n defaultBranch,\n },\n approvalTool: deps.approvalTool,\n status: null,\n } as Components.Schemas.Import;\n try {\n // Check to see if there are any PR\n const openImportPr = await deps.gitApiService.findImportOpenPr(\n deps.logger,\n {\n repoUrl: repoUrl,\n includeCatalogInfoContent,\n },\n );\n\n if (!openImportPr?.prUrl) {\n const catalogLocations = (\n await deps.catalogHttpClient.listCatalogUrlLocations()\n ).uniqueCatalogUrlLocations.keys();\n\n const catalogUrl = getCatalogUrl(deps.config, repoUrl, defaultBranch);\n let exists = false;\n for (const loc of catalogLocations) {\n if (loc === catalogUrl) {\n exists = true;\n break;\n }\n }\n if (\n exists &&\n (await deps.gitApiService.hasFileInRepo({\n repoUrl,\n defaultBranch,\n fileName: getCatalogFilename(deps.config),\n }))\n ) {\n result.status = 'ADDED';\n // Force a refresh of the Location, so that the entities from the catalog-info.yaml can show up quickly (not guaranteed however).\n await deps.catalogHttpClient.refreshLocationByRepoUrl(\n repoUrl,\n defaultBranch,\n );\n }\n // No import PR => let's determine last update from the repository\n const ghRepo =\n await deps.gitApiService.getRepositoryFromIntegrations(repoUrl);\n result.lastUpdate = ghRepo.repository?.updated_at ?? undefined;\n return {\n statusCode: 200,\n responseBody: result,\n };\n }\n result.status = 'WAIT_PR_APPROVAL';\n result[deps.approvalTool === 'GITLAB' ? 'gitlab' : 'github'] = {\n pullRequest: {\n number: openImportPr.prNum,\n url: openImportPr.prUrl,\n title: openImportPr.prTitle,\n body: openImportPr.prBody,\n catalogInfoContent: openImportPr.prCatalogInfoContent,\n },\n };\n\n result.lastUpdate = openImportPr.lastUpdate;\n } catch (error: any) {\n errors.push(error.message);\n result.errors = errors;\n if (error.message?.includes('Not Found')) {\n return {\n statusCode: 404,\n responseBody: result,\n };\n }\n result.status = 'PR_ERROR';\n }\n\n return {\n statusCode: 200,\n responseBody: result,\n };\n}\n\nexport async function findTaskImportStatusByRepo(\n deps: {\n logger: LoggerService;\n config: Config;\n githubApiService: GithubApiService;\n gitlabApiService: GitlabApiService;\n catalogHttpClient: CatalogHttpClient;\n repositoryDao: RepositoryDao<'repositories'>;\n taskDao: ScaffolderTaskDao;\n taskLocationsDao: TaskLocationsDao;\n discovery: DiscoveryService;\n auth: AuthService;\n },\n repoUrl: string,\n skipTasks?: boolean,\n): Promise<HandlerResponse<Components.Schemas.Import>> {\n deps.logger.debug(`Getting bulk import job status for ${repoUrl}.`);\n\n const gitUrl = gitUrlParse(repoUrl);\n\n const errors: string[] = [];\n const result: Components.Schemas.Import = {\n id: repoUrl,\n repository: {\n url: repoUrl,\n name: gitUrl.name,\n organization: gitUrl.organization,\n id: `${gitUrl.organization}/${gitUrl.name}`,\n },\n };\n try {\n const repository = await deps.repositoryDao.findRepositoryByUrl(repoUrl);\n if (!repository) {\n throw new NotFoundError(`Repository ${repoUrl} info was not found`);\n }\n\n const task = await deps.taskDao.lastExecutedTaskByRepoId(repository?.id);\n if (!task) {\n throw new NotFoundError(\n `Unable to find scaffolder task for repository: ${repository?.id}`,\n );\n }\n\n const scaffolderUrl = await deps.discovery.getBaseUrl('scaffolder');\n const { token } = await deps.auth.getPluginRequestToken({\n onBehalfOf: await deps.auth.getOwnServiceCredentials(),\n targetPluginId: 'scaffolder',\n });\n\n const response = await fetch(`${scaffolderUrl}/v2/tasks/${task.taskId}`, {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n });\n if (!skipTasks) {\n const tasks = await deps.taskDao.findTasksByRepositoryId(repository.id);\n const tasksWithLocations = await Promise.all(\n tasks.map(async taskItem => {\n const locations = await deps.taskLocationsDao.findLocationsByTaskId(\n taskItem.taskId,\n );\n const taskLocations = locations.map(location => location.location);\n return {\n ...taskItem,\n locations: taskLocations,\n };\n }),\n );\n result.tasks = tasksWithLocations;\n }\n\n result.task = { taskId: task.taskId };\n let data;\n if (response.ok) {\n data = await response.json();\n result.lastUpdate = data.lastHeartbeatAt;\n\n const approvalTool =\n repository.approvalTool as unknown as Components.Schemas.ApprovalTool;\n const pullRequest = await parsePullOrMergeRequestInfo(\n data.state?.checkpoints,\n {\n githubApiService: deps.githubApiService,\n gitlabApiService: deps.gitlabApiService,\n approvalTool,\n logger: deps.logger,\n repoUrl,\n },\n );\n if (pullRequest && approvalTool === 'GITLAB') {\n result.gitlab = { pullRequest };\n }\n if (pullRequest && approvalTool === 'GIT') {\n result.github = { pullRequest };\n }\n\n result.status =\n `TASK_${(data.status as string)?.toLocaleUpperCase()}` as Components.Schemas.TaskImportStatus;\n } else {\n const errMsg =\n (await response.text()) ??\n `Failed to fetch task ${task.taskId}. Response status: ${response.status}`;\n throw new Error(errMsg);\n }\n } catch (error: any) {\n errors.push(error.message);\n result.errors = errors;\n result.status = 'TASK_FETCH_FAILED';\n if (error.name?.includes('NotFoundError')) {\n return {\n statusCode: 404,\n responseBody: result,\n };\n }\n }\n\n return {\n statusCode: 200,\n responseBody: result,\n };\n}\n\nexport async function findOrchestratorImportStatusByRepo(\n deps: {\n logger: LoggerService;\n orchestratorRepositoryDao: RepositoryDao<'orchestrator_repositories'>;\n orchestratorWorkflowDao: OrchestratorWorkflowDao;\n discovery: DiscoveryService;\n },\n repoUrl: string,\n token: string,\n skipWorkflows?: boolean,\n): Promise<HandlerResponse<Components.Schemas.Import>> {\n deps.logger.debug(\n `Getting orchestrator workflow import job status for ${repoUrl}.`,\n );\n\n const gitUrl = gitUrlParse(repoUrl);\n\n const errors: string[] = [];\n const result: Components.Schemas.Import = {\n id: repoUrl,\n repository: {\n url: repoUrl,\n name: gitUrl.name,\n organization: gitUrl.organization,\n id: `${gitUrl.organization}/${gitUrl.name}`,\n },\n };\n try {\n const repository =\n await deps.orchestratorRepositoryDao.findRepositoryByUrl(repoUrl);\n if (repository) {\n const workflow =\n await deps.orchestratorWorkflowDao.lastExecutedWorkflowByRepoId(\n repository.id,\n );\n if (!workflow) {\n throw new NotFoundError(\n `Workflow for repository ${repoUrl} was not found`,\n );\n }\n if (workflow.instanceId) {\n const baseUrl = await deps.discovery.getBaseUrl('orchestrator');\n const orchestratorApi = new DefaultApi(new Configuration(), baseUrl);\n const response = await orchestratorApi.getInstanceById(\n workflow.instanceId,\n {\n headers: {\n Authorization: `Bearer ${token}`,\n 'Content-Type': 'application/json',\n },\n },\n );\n\n const instance = response.data;\n if (instance) {\n result.workflow = {\n workflowId: instance.id,\n };\n if (!skipWorkflows) {\n const workflows =\n await deps.orchestratorWorkflowDao.findWorkflowsByRepositoryId(\n repository.id,\n );\n result.workflows = workflows.map((w: OrchestratorWorkflow) => ({\n workflowId: w.instanceId,\n }));\n }\n\n result.approvalTool =\n repository.approvalTool as unknown as Components.Schemas.ApprovalTool;\n result.lastUpdate = instance.end;\n const status =\n `WORKFLOW_${(instance.state as string)?.toLocaleUpperCase()}` as Components.Schemas.WorkflowImportStatus;\n result.status = status;\n }\n }\n }\n } catch (error: any) {\n errors.push(error.message);\n result.errors = errors;\n result.status = 'WORKFLOW_FETCH_FAILED';\n if (error.name?.includes('NotFoundError')) {\n return {\n statusCode: 404,\n responseBody: result,\n };\n }\n }\n\n return {\n statusCode: 200,\n responseBody: result,\n };\n}\n\nasync function parsePullOrMergeRequestInfo(\n checkpoints: Record<string, any>,\n {\n githubApiService,\n gitlabApiService,\n approvalTool,\n logger,\n repoUrl,\n }: {\n githubApiService: GithubApiService;\n gitlabApiService: GitlabApiService;\n approvalTool: Components.Schemas.ApprovalTool;\n logger: LoggerService;\n repoUrl: string;\n },\n): Promise<Components.Schemas.PullRequest | undefined> {\n // return errors ?\n if (approvalTool !== 'GITLAB' && approvalTool !== 'GIT') {\n return undefined;\n }\n const gitApiService =\n approvalTool === 'GITLAB' ? gitlabApiService : githubApiService;\n\n for (const key in checkpoints) {\n if (!checkpoints.hasOwnProperty(key)) {\n continue;\n }\n try {\n if (\n key.startsWith('v1.task.checkpoint.publish.create.pr') ||\n key.startsWith('v1.task.checkpoint.publish.create.mr')\n ) {\n const url =\n checkpoints[key]?.value?.html_url ??\n checkpoints[key]?.value?.mrWebUrl;\n if (!url) {\n continue;\n }\n const prNumber = Number.parseInt(url.split('/').pop()!, 10);\n const prDetails = await gitApiService.getPullRequest(repoUrl, prNumber);\n\n let catalogInfoContent: string | undefined;\n if (prDetails.prSha) {\n catalogInfoContent = await gitApiService.getCatalogInfoFile(logger, {\n repoUrl,\n prHeadSha: prDetails.prSha,\n prNumber,\n });\n }\n return {\n url,\n number: prNumber,\n title: prDetails.title,\n body: prDetails.body,\n status: prDetails.merged ? 'PR_MERGED' : 'WAIT_PR_APPROVAL',\n catalogInfoContent,\n };\n }\n } catch (err) {\n logger.warn(`Error while processing checkpoint ${key}: ${err}`);\n continue;\n }\n }\n\n return undefined;\n}\n\nexport async function deleteImportByRepo(\n deps: {\n logger: LoggerService;\n config: Config;\n gitApiService: GitApiService;\n catalogHttpClient: CatalogHttpClient;\n },\n repoUrl: string,\n defaultBranch?: string,\n): Promise<HandlerResponse<void>> {\n deps.logger.debug(`Deleting bulk import job status for ${repoUrl}..`);\n\n // Check to see if there are any PR\n const openImportPr = await deps.gitApiService.findImportOpenPr(deps.logger, {\n repoUrl: repoUrl,\n });\n\n const gitUrl = gitUrlParse(repoUrl);\n if (openImportPr?.prUrl) {\n // Close PR\n const appTitle =\n deps.config.getOptionalString('app.title') ?? 'Red Hat Developer Hub';\n const appBaseUrl = deps.config.getString('app.baseUrl');\n\n await deps.gitApiService.closeImportPR(deps.logger, {\n repoUrl,\n gitUrl,\n comment: `Closing PR upon request for bulk import deletion. This request was created from [${appTitle}](${appBaseUrl}).`,\n });\n }\n // Also delete the import branch, so that it is not outdated if we try later to import the repo again\n await deps.gitApiService.deleteImportBranch({\n repoUrl,\n gitUrl,\n });\n // Remove Location from catalog\n const catalogUrl = getCatalogUrl(deps.config, repoUrl, defaultBranch);\n const findLocationFrom = (list: { id?: string; target: string }[]) => {\n for (const loc of list) {\n if (loc.target === catalogUrl) {\n return loc.id;\n }\n }\n return undefined;\n };\n\n const locationId = findLocationFrom(\n (\n await deps.catalogHttpClient.listCatalogUrlLocationsByIdFromLocationsEndpoint()\n ).locations,\n );\n if (locationId) {\n await deps.catalogHttpClient.deleteCatalogLocationById(locationId);\n }\n\n return {\n statusCode: 204,\n responseBody: undefined,\n };\n}\n\nexport async function deleteRepositoryRecord<\n DAO extends RepositoryDao<RepositoryName>,\n>(\n deps: {\n logger: LoggerService;\n dao: DAO;\n },\n repoUrl: string,\n): Promise<HandlerResponse<void>> {\n deps.logger.debug(`Deleting repository from database by name ${repoUrl}...`);\n try {\n await deps.dao.deleteRepository(repoUrl);\n\n return {\n statusCode: 204,\n responseBody: undefined,\n };\n } catch (error: any) {\n deps.logger.error(\n `Failed to delete repository from database by url ${repoUrl}`,\n error,\n );\n return {\n statusCode: 500,\n };\n }\n}\n"],"names":["DefaultSortColumn","DefaultSortOrder","getNestedValue","DefaultPageNumber","DefaultPageSize","getCatalogFilename","parseGitURLForApprovalTool","imports","paginateArray","logErrorIfNeeded","getCatalogUrl","gitUrlParse","errors","NotFoundError","DefaultApi","Configuration"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"bulkImports.cjs.js","sources":["../../../../src/service/handlers/import/bulkImports.ts"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\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 type {\n AuthService,\n DiscoveryService,\n LoggerService,\n} from '@backstage/backend-plugin-api';\nimport type { Config } from '@backstage/config';\nimport { NotFoundError } from '@backstage/errors';\n\nimport gitUrlParse from 'git-url-parse';\n\nimport {\n Configuration,\n DefaultApi,\n} from '@red-hat-developer-hub/backstage-plugin-orchestrator-common';\n\nimport { CatalogHttpClient } from '../../../catalog/catalogHttpClient';\nimport type { CatalogInfoGenerator } from '../../../catalog/catalogInfoGenerator';\nimport {\n getCatalogFilename,\n getCatalogUrl,\n} from '../../../catalog/catalogUtils';\nimport {\n OrchestratorWorkflow,\n OrchestratorWorkflowDao,\n RepositoryDao,\n RepositoryName,\n ScaffolderTaskDao,\n TaskLocationsDao,\n} from '../../../database/repositoryDao';\nimport type { Components, Paths } from '../../../generated/openapi';\nimport type { GithubApiService } from '../../../github';\nimport { GitlabApiService } from '../../../gitlab';\nimport {\n getNestedValue,\n logErrorIfNeeded,\n paginateArray,\n parseGitURLForApprovalTool,\n} from '../../../helpers';\nimport { GitApiService } from '../../../scm/GitApiService';\nimport {\n DefaultPageNumber,\n DefaultPageSize,\n DefaultSortColumn,\n DefaultSortOrder,\n type HandlerResponse,\n} from '../handlers';\n\ntype CreateImportDryRunStatus =\n | 'CATALOG_ENTITY_CONFLICT'\n | 'CATALOG_INFO_FILE_EXISTS_IN_REPO'\n | 'CODEOWNERS_FILE_NOT_FOUND_IN_REPO'\n | 'REPO_EMPTY';\n\ntype FindAllImportsResponse =\n | Components.Schemas.Import[]\n | Components.Schemas.ImportJobListV2;\n\nexport function sortImports(\n imports: Components.Schemas.Import[],\n sortColumn: Components.Parameters.SortColumnQueryParam = DefaultSortColumn,\n sortOrder: Components.Parameters.SortOrderQueryParam = DefaultSortOrder,\n) {\n imports.sort((a, b) => {\n const value1 = getNestedValue(a, sortColumn);\n const value2 = getNestedValue(b, sortColumn);\n // Handle cases where values are undefined\n if (value1 === undefined && value2 === undefined) return 0;\n if (value1 === undefined) return sortOrder === 'asc' ? -1 : 1;\n if (value2 === undefined) return sortOrder === 'asc' ? 1 : -1;\n\n if (sortColumn === 'lastUpdate') {\n const date1 = new Date(value1); // Convert string to Date object\n const date2 = new Date(value2); // Convert string to Date object\n // Compare dates\n return sortOrder === 'asc'\n ? date2.getTime() - date1.getTime()\n : date1.getTime() - date2.getTime();\n }\n // Compare values based on sort order\n return sortOrder === 'asc'\n ? value1.localeCompare(value2)\n : value2.localeCompare(value1);\n });\n}\n\nexport async function findAllImports(\n deps: {\n logger: LoggerService;\n config: Config;\n gitlabApiService: GitlabApiService;\n githubApiService: GithubApiService;\n catalogHttpClient: CatalogHttpClient;\n },\n requestHeaders?: {\n apiVersion?: Paths.FindAllImports.Parameters.ApiVersion;\n },\n queryParams?: {\n search?: string;\n pageNumber?: number;\n pageSize?: number;\n sortColumn?: Components.Parameters.SortColumnQueryParam;\n sortOrder?: Components.Parameters.SortOrderQueryParam;\n },\n): Promise<HandlerResponse<FindAllImportsResponse>> {\n const apiVersion = requestHeaders?.apiVersion ?? 'v1';\n const search = queryParams?.search;\n const pageNumber = queryParams?.pageNumber ?? DefaultPageNumber;\n const pageSize = queryParams?.pageSize ?? DefaultPageSize;\n const sortColumn = queryParams?.sortColumn ?? DefaultSortColumn;\n const sortOrder = queryParams?.sortOrder ?? DefaultSortOrder;\n\n const catalogFilename = getCatalogFilename(deps.config);\n\n const allLocations = (\n await deps.catalogHttpClient.listCatalogUrlLocations(\n search,\n pageNumber,\n pageSize,\n )\n ).uniqueCatalogUrlLocations;\n\n // resolve default branches for each unique repo URL from GH,\n // because we cannot easily determine that from the location target URL.\n // It can be 'main' or something more convoluted like 'our/awesome/main'.\n const defaultBranchByRepoUrl = await resolveReposDefaultBranches(\n deps.logger,\n deps.gitlabApiService,\n deps.githubApiService,\n allLocations.keys(),\n catalogFilename,\n );\n\n // filter out locations that do not match what we are expecting, i.e.:\n // an URL to a catalog-info YAML file at the root of the repo\n const importCandidates = findImportCandidates(\n allLocations.keys(),\n defaultBranchByRepoUrl,\n catalogFilename,\n );\n\n // Keep only repos that are accessible from the configured GH/GL integrations\n const importsReachableFromGHIntegrations =\n await deps.githubApiService.filterLocationsAccessibleFromIntegrations(\n importCandidates.filter(val => {\n return parseGitURLForApprovalTool(val) === 'GIT';\n }),\n );\n\n const importsReachableFromGLIntegrations =\n await deps.gitlabApiService.filterLocationsAccessibleFromIntegrations(\n importCandidates.filter(val => {\n return parseGitURLForApprovalTool(val) === 'GITLAB';\n }),\n );\n\n // Merge the two lists together and map the appropriate approvalTool\n const mergedReachbleFromIntegrations = importsReachableFromGHIntegrations\n .map(val => {\n return {\n loc: val,\n approvalTool: 'GIT',\n };\n })\n .concat(\n importsReachableFromGLIntegrations.map(val => {\n return {\n loc: val,\n approvalTool: 'GITLAB',\n };\n }),\n );\n\n const repoUrlToLocation = new Map<string, string>();\n\n // now fetch the import statuses in different promises\n const importStatusPromises: Promise<\n HandlerResponse<Components.Schemas.Import>\n >[] = [];\n for (const imports of mergedReachbleFromIntegrations) {\n const repoUrl = repoUrlFromLocation(imports.loc);\n if (!repoUrl) {\n continue;\n }\n repoUrlToLocation.set(repoUrl, imports.loc);\n\n importStatusPromises.push(\n findImportStatusByRepo(\n {\n logger: deps.logger,\n config: deps.config,\n gitApiService:\n imports.approvalTool === 'GITLAB'\n ? deps.gitlabApiService\n : deps.githubApiService,\n catalogHttpClient: deps.catalogHttpClient,\n approvalTool: imports.approvalTool,\n },\n repoUrl,\n defaultBranchByRepoUrl.get(repoUrl),\n false,\n ),\n );\n }\n\n const result = await Promise.all(importStatusPromises);\n const imports = result\n .filter(res => res.responseBody)\n .map(res => res.responseBody!)\n .map(res => {\n const key = res?.repository?.url;\n const location = key ? repoUrlToLocation.get(key) : undefined;\n return {\n ...res,\n source: location ? allLocations.get(location)?.source : undefined,\n };\n });\n\n // sorting the output to make it deterministic and easy to navigate in the UI\n\n sortImports(imports, sortColumn, sortOrder);\n const paginated = paginateArray(imports, pageNumber, pageSize);\n if (apiVersion === 'v1') {\n return {\n statusCode: 200,\n responseBody: paginated.result,\n };\n }\n return {\n statusCode: 200,\n responseBody: {\n imports: paginated.result,\n totalCount: paginated.totalCount,\n page: pageNumber,\n size: pageSize,\n },\n };\n}\n\nasync function resolveReposDefaultBranches(\n logger: LoggerService,\n gitlabApiService: GitlabApiService,\n githubApiService: GithubApiService,\n allLocations: Iterable<string>,\n catalogFilename: string,\n) {\n const defaultBranchByRepoUrlPromises: Promise<{\n repoUrl: string;\n defaultBranch?: string;\n }>[] = [];\n for (const loc of allLocations) {\n // loc has the following format: https://github.com/<org>/<repo>/blob/<default-branch>/catalog-info.yaml\n // but it can have a more convoluted format like 'https://github.com/redhat-developer/rhdh-plugins/blob/main/plugins/scaffolder-annotator-action/examples/templates/01-scaffolder-template.yaml'\n // if registered manually from the 'Register existing component' feature in Backstage.\n if (!loc.endsWith(catalogFilename)) {\n logger.debug(\n `Ignored location ${loc} because it does not point to a file named ${catalogFilename}`,\n );\n continue;\n }\n const repoUrl = repoUrlFromLocation(loc);\n if (!repoUrl) {\n continue;\n }\n // Have to do this for Both the gitlab/github, possibly a better way?\n // Should probably parse the URL to figure out which to use?\n defaultBranchByRepoUrlPromises.push(\n (parseGitURLForApprovalTool(repoUrl) === 'GITLAB'\n ? gitlabApiService\n : githubApiService\n )\n .getRepositoryFromIntegrations(repoUrl)\n .then(resp => {\n return { repoUrl, defaultBranch: resp?.repository?.default_branch };\n })\n .catch((err: any) => {\n logErrorIfNeeded(\n logger,\n `Ignored repo ${repoUrl} due to an error while fetching details from GitHub`,\n err,\n );\n return {\n repoUrl,\n defaultBranch: undefined,\n };\n }),\n );\n }\n const defaultBranchesResponses = await Promise.all(\n defaultBranchByRepoUrlPromises,\n );\n return new Map(\n defaultBranchesResponses\n .flat()\n .filter(r => r.defaultBranch)\n .map(r => [r.repoUrl, r.defaultBranch!]),\n );\n}\n\nfunction repoUrlFromLocation(loc: string) {\n const split = loc.split('/blob/');\n if (split.length < 2) {\n return undefined;\n }\n return split[0];\n}\n\nfunction findImportCandidates(\n allLocations: Iterable<string>,\n defaultBranchByRepoUrl: Map<string, string>,\n catalogFilename: string,\n) {\n const filteredLocations: string[] = [];\n for (const loc of allLocations) {\n const repoUrl = repoUrlFromLocation(loc);\n if (!repoUrl) {\n continue;\n }\n\n const defaultBranch = defaultBranchByRepoUrl.get(repoUrl);\n if (!defaultBranch) {\n continue;\n }\n if (loc !== `${repoUrl}/blob/${defaultBranch}/${catalogFilename}`) {\n // Because users can use the \"Register existing component\" workflow to register a Location\n // using any file path in the repo, we consider a repository as an Import Location only\n // if it is at the root of the repository, because that is what the import PR ultimately does.\n continue;\n }\n filteredLocations.push(loc);\n }\n return filteredLocations;\n}\n\nasync function createPR(\n gitApiService: GitApiService,\n logger: LoggerService,\n req: Components.Schemas.ImportRequest,\n gitUrl: gitUrlParse.GitUrl,\n catalogInfoGenerator: CatalogInfoGenerator,\n config: Config,\n) {\n const appTitle =\n config.getOptionalString('app.title') ?? 'Red Hat Developer Hub';\n const appBaseUrl = config.getString('app.baseUrl');\n const catalogFileName = getCatalogFilename(config);\n return await gitApiService.submitPrToRepo(logger, {\n repoUrl: req.repository.url,\n gitUrl: gitUrl,\n defaultBranch: req.repository.defaultBranch,\n catalogInfoContent:\n req.catalogInfoContent ??\n (await catalogInfoGenerator.generateDefaultCatalogInfoContent(\n req.repository.url,\n )),\n prTitle:\n req[req.approvalTool === 'GITLAB' ? 'gitlab' : 'github']?.pullRequest\n ?.title ?? `Add ${catalogFileName}`,\n prBody:\n req[req.approvalTool === 'GITLAB' ? 'gitlab' : 'github']?.pullRequest\n ?.body ??\n `\nThis pull request adds a **Backstage entity metadata file** to this repository so that the component can be added to a Backstage application.\n\nAfter this pull request is merged, the component will become available in the [${appTitle} software catalog](${appBaseUrl}).\n\nFor more information, read an [overview of the Backstage software catalog](https://backstage.io/docs/features/software-catalog/).\n`,\n });\n}\n\nasync function handleAddedReposFromCreateImportJobs(\n deps: {\n logger: LoggerService;\n config: Config;\n auth: AuthService;\n gitlabApiService: GitlabApiService;\n githubApiService: GithubApiService;\n catalogInfoGenerator: CatalogInfoGenerator;\n catalogHttpClient: CatalogHttpClient;\n },\n importRequests: Components.Schemas.ImportRequest[],\n) {\n const result: Components.Schemas.Import[] = [];\n\n for (const req of importRequests) {\n // Check if repo is already imported\n const repoCatalogUrl = getCatalogUrl(\n deps.config,\n req.repository.url,\n req.repository.defaultBranch,\n );\n const hasLocation =\n await deps.catalogHttpClient.verifyLocationExistence(repoCatalogUrl);\n if (!hasLocation) {\n continue;\n }\n const gitApiService =\n req.approvalTool === 'GITLAB'\n ? deps.gitlabApiService\n : deps.githubApiService;\n const hasCatalogInfoFileInRepo = await gitApiService.hasFileInRepo({\n repoUrl: req.repository.url,\n defaultBranch: req.repository.defaultBranch,\n fileName: getCatalogFilename(deps.config),\n });\n if (!hasCatalogInfoFileInRepo) {\n continue;\n }\n\n const ghRepo = await gitApiService.getRepositoryFromIntegrations(\n req.repository.url,\n );\n\n // Force a refresh of the Location, so that the entities from the catalog-info.yaml can show up quickly (not guaranteed however).\n await deps.catalogHttpClient.refreshLocationByRepoUrl(\n req.repository.url,\n req.repository.defaultBranch,\n );\n\n const gitUrl = gitUrlParse(req.repository.url);\n result.push({\n status: 'ADDED',\n lastUpdate: ghRepo?.repository?.updated_at ?? undefined,\n repository: {\n url: req.repository.url,\n name: gitUrl.name,\n organization: gitUrl.organization,\n },\n });\n }\n return result;\n}\n\nasync function handlePrCreationRequest(\n deps: {\n logger: LoggerService;\n config: Config;\n auth: AuthService;\n gitlabApiService: GitlabApiService;\n githubApiService: GithubApiService;\n catalogInfoGenerator: CatalogInfoGenerator;\n catalogHttpClient: CatalogHttpClient;\n },\n req: Components.Schemas.ImportRequest,\n gitUrl: gitUrlParse.GitUrl,\n): Promise<Components.Schemas.Import> {\n const repoCatalogUrl = getCatalogUrl(\n deps.config,\n req.repository.url,\n req.repository.defaultBranch,\n );\n const gitApiService =\n req.approvalTool === 'GITLAB'\n ? deps.gitlabApiService\n : deps.githubApiService;\n const prToRepo = await createPR(\n gitApiService,\n deps.logger,\n req,\n gitUrl,\n deps.catalogInfoGenerator,\n deps.config,\n );\n if (prToRepo.errors && prToRepo.errors.length > 0) {\n return {\n errors: prToRepo.errors,\n status: 'PR_ERROR',\n repository: req.repository,\n };\n }\n if (prToRepo.prUrl) {\n deps.logger.debug(`Created new PR from request: ${prToRepo.prUrl}`);\n }\n\n // Create Location\n await deps.catalogHttpClient.possiblyCreateLocation(repoCatalogUrl);\n\n if (prToRepo.hasChanges === false) {\n deps.logger.debug(\n `No bulk import PR created on ${req.repository.url} since its default branch (${req.repository.defaultBranch}) already contains a catalog-info file`,\n );\n\n // Force a refresh of the Location, so that the entities from the catalog-info.yaml can show up quickly (not guaranteed however).\n await deps.catalogHttpClient.refreshLocationByRepoUrl(\n req.repository.url,\n req.repository.defaultBranch,\n );\n return {\n status: 'ADDED',\n lastUpdate: prToRepo.lastUpdate,\n repository: {\n url: req.repository.url,\n name: gitUrl.name,\n organization: gitUrl.organization,\n },\n };\n }\n\n return {\n approvalTool: req.approvalTool ?? 'GIT',\n errors: prToRepo.errors,\n status: 'WAIT_PR_APPROVAL',\n lastUpdate: prToRepo.lastUpdate,\n repository: {\n url: req.repository.url,\n name: gitUrl.name,\n organization: gitUrl.organization,\n },\n [req.approvalTool === 'GITLAB' ? 'gitlab' : 'github']: {\n pullRequest: {\n url: prToRepo.prUrl,\n number: prToRepo.prNumber,\n },\n },\n };\n}\n\nexport async function createImportJobs(\n deps: {\n logger: LoggerService;\n config: Config;\n auth: AuthService;\n gitlabApiService: GitlabApiService;\n githubApiService: GithubApiService;\n catalogInfoGenerator: CatalogInfoGenerator;\n catalogHttpClient: CatalogHttpClient;\n },\n reqParams: {\n importRequests: Paths.CreateImportJobs.RequestBody;\n dryRun?: boolean;\n },\n): Promise<HandlerResponse<Components.Schemas.Import[]>> {\n const dryRun = reqParams.dryRun ?? false;\n const importRequests = reqParams.importRequests;\n deps.logger.debug(\n `Handling request to import ${importRequests?.length} repo(s) (dryRun=${dryRun})..`,\n );\n\n if (importRequests.length === 0) {\n deps.logger.debug('Missing import requests from request body');\n return {\n statusCode: 400,\n responseBody: [],\n };\n }\n\n if (dryRun) {\n return {\n statusCode: 202,\n responseBody: await dryRunCreateImportJobs(deps, importRequests),\n };\n }\n\n const result: Components.Schemas.Import[] = [];\n\n const addedRepos = await handleAddedReposFromCreateImportJobs(\n deps,\n importRequests,\n );\n result.push(...addedRepos);\n const addedReposMap = new Map(\n addedRepos.map(res => [res.repository?.url, res]),\n );\n const remainingRequests = importRequests.filter(\n req => !addedReposMap.has(req.repository.url),\n );\n\n for (const req of remainingRequests) {\n const gitUrl = gitUrlParse(req.repository.url);\n\n // Create PR\n try {\n result.push(await handlePrCreationRequest(deps, req, gitUrl));\n } catch (error: any) {\n result.push({\n errors: [error.message],\n status: 'PR_ERROR',\n repository: {\n url: req.repository.url,\n name: gitUrl.name,\n organization: gitUrl.organization,\n },\n } as Components.Schemas.Import);\n }\n }\n\n sortImports(result);\n\n return {\n statusCode: 202,\n responseBody: result,\n };\n}\n\nasync function dryRunCreateImportJobs(\n deps: {\n logger: LoggerService;\n config: Config;\n auth: AuthService;\n gitlabApiService: GitlabApiService;\n githubApiService: GithubApiService;\n catalogInfoGenerator: CatalogInfoGenerator;\n catalogHttpClient: CatalogHttpClient;\n },\n importRequests: Paths.CreateImportJobs.RequestBody,\n) {\n const result: Components.Schemas.Import[] = [];\n for (const req of importRequests) {\n const gitUrl = gitUrlParse(req.repository.url);\n\n const dryRunChecks = await performDryRunChecks(deps, req);\n if (dryRunChecks.errors?.length > 0) {\n deps.logger.warn(\n `Errors while performing dry-run checks: ${dryRunChecks.errors}`,\n );\n }\n result.push({\n errors: dryRunChecks.dryRunStatuses,\n catalogEntityName: req.catalogEntityName,\n repository: {\n url: req.repository.url,\n name: gitUrl.name,\n organization: gitUrl.organization,\n },\n });\n }\n return result;\n}\n\nasync function performDryRunChecks(\n deps: {\n logger: LoggerService;\n auth: AuthService;\n config: Config;\n gitlabApiService: GitlabApiService;\n githubApiService: GithubApiService;\n catalogHttpClient: CatalogHttpClient;\n },\n req: Components.Schemas.ImportRequest,\n): Promise<{ dryRunStatuses: CreateImportDryRunStatus[]; errors: string[] }> {\n const checkCatalog = async (\n catalogEntityName: string,\n ): Promise<{\n dryRunStatuses?: CreateImportDryRunStatus[];\n errors?: string[];\n }> => {\n const hasEntity =\n await deps.catalogHttpClient.hasEntityInCatalog(catalogEntityName);\n if (hasEntity) {\n return { dryRunStatuses: ['CATALOG_ENTITY_CONFLICT'] };\n }\n return {};\n };\n\n const gitApiService =\n req.approvalTool === 'GITLAB'\n ? deps.gitlabApiService\n : deps.githubApiService;\n const checkEmptyRepo = async (): Promise<{\n dryRunStatuses?: CreateImportDryRunStatus[];\n errors?: string[];\n }> => {\n const empty = await gitApiService.isRepoEmpty({\n repoUrl: req.repository.url,\n });\n if (empty) {\n return {\n dryRunStatuses: ['REPO_EMPTY'],\n };\n }\n return {};\n };\n\n const checkCatalogInfoPresenceInRepo = async (): Promise<{\n dryRunStatuses?: CreateImportDryRunStatus[];\n errors?: string[];\n }> => {\n const exists = await gitApiService.hasFileInRepo({\n repoUrl: req.repository.url,\n defaultBranch: req.repository.defaultBranch,\n fileName: getCatalogFilename(deps.config),\n });\n if (exists) {\n return {\n dryRunStatuses: ['CATALOG_INFO_FILE_EXISTS_IN_REPO'],\n };\n }\n return {};\n };\n\n const checkCodeOwnersFileInRepo = async (): Promise<{\n dryRunStatuses?: CreateImportDryRunStatus[];\n errors?: string[];\n }> => {\n const gitDirLocation =\n req.approvalTool === 'GITLAB' ? '.gitlab' : '.github';\n const exists = await gitApiService.hasFileInRepo({\n repoUrl: req.repository.url,\n defaultBranch: req.repository.defaultBranch,\n fileName: `${gitDirLocation}/CODEOWNERS`,\n });\n if (!exists) {\n return {\n dryRunStatuses: ['CODEOWNERS_FILE_NOT_FOUND_IN_REPO'],\n };\n }\n return {};\n };\n\n const dryRunStatuses: CreateImportDryRunStatus[] = [];\n const errors: string[] = [];\n const allChecksFn = [checkEmptyRepo(), checkCatalogInfoPresenceInRepo()];\n if (req.catalogEntityName?.trim()) {\n allChecksFn.push(checkCatalog(req.catalogEntityName));\n }\n if (req.codeOwnersFileAsEntityOwner) {\n allChecksFn.push(checkCodeOwnersFileInRepo());\n }\n const allChecks = await Promise.all(allChecksFn);\n allChecks.flat().forEach(res => {\n if (res.dryRunStatuses) {\n dryRunStatuses.push(...res.dryRunStatuses);\n }\n if (res.errors) {\n errors.push(...res.errors);\n }\n });\n\n dryRunStatuses.sort((a, b) => a.localeCompare(b));\n\n return {\n dryRunStatuses,\n errors,\n };\n}\n\nexport async function findImportStatusByRepo(\n deps: {\n logger: LoggerService;\n config: Config;\n gitApiService: GitlabApiService | GithubApiService;\n catalogHttpClient: CatalogHttpClient;\n approvalTool: string | undefined;\n },\n repoUrl: string,\n defaultBranch?: string,\n includeCatalogInfoContent?: boolean,\n): Promise<HandlerResponse<Components.Schemas.Import>> {\n deps.logger.debug(`Getting bulk import job status for ${repoUrl}..`);\n\n const gitUrl = gitUrlParse(repoUrl);\n\n const errors: string[] = [];\n const result = {\n id: repoUrl,\n repository: {\n url: repoUrl,\n name: gitUrl.name,\n organization: gitUrl.organization,\n id: `${gitUrl.organization}/${gitUrl.name}`,\n defaultBranch,\n },\n approvalTool: deps.approvalTool,\n status: null,\n } as Components.Schemas.Import;\n try {\n // Check to see if there are any PR\n const openImportPr = await deps.gitApiService.findImportOpenPr(\n deps.logger,\n {\n repoUrl: repoUrl,\n includeCatalogInfoContent,\n },\n );\n\n if (!openImportPr?.prUrl) {\n const catalogLocations = (\n await deps.catalogHttpClient.listCatalogUrlLocations()\n ).uniqueCatalogUrlLocations.keys();\n\n const catalogUrl = getCatalogUrl(deps.config, repoUrl, defaultBranch);\n let exists = false;\n for (const loc of catalogLocations) {\n if (loc === catalogUrl) {\n exists = true;\n break;\n }\n }\n if (\n exists &&\n (await deps.gitApiService.hasFileInRepo({\n repoUrl,\n defaultBranch,\n fileName: getCatalogFilename(deps.config),\n }))\n ) {\n result.status = 'ADDED';\n // Force a refresh of the Location, so that the entities from the catalog-info.yaml can show up quickly (not guaranteed however).\n await deps.catalogHttpClient.refreshLocationByRepoUrl(\n repoUrl,\n defaultBranch,\n );\n }\n // No import PR => let's determine last update from the repository\n const ghRepo =\n await deps.gitApiService.getRepositoryFromIntegrations(repoUrl);\n result.lastUpdate = ghRepo.repository?.updated_at ?? undefined;\n return {\n statusCode: 200,\n responseBody: result,\n };\n }\n result.status = 'WAIT_PR_APPROVAL';\n result[deps.approvalTool === 'GITLAB' ? 'gitlab' : 'github'] = {\n pullRequest: {\n number: openImportPr.prNum,\n url: openImportPr.prUrl,\n title: openImportPr.prTitle,\n body: openImportPr.prBody,\n catalogInfoContent: openImportPr.prCatalogInfoContent,\n },\n };\n\n result.lastUpdate = openImportPr.lastUpdate;\n } catch (error: any) {\n errors.push(error.message);\n result.errors = errors;\n if (error.message?.includes('Not Found')) {\n return {\n statusCode: 404,\n responseBody: result,\n };\n }\n result.status = 'PR_ERROR';\n }\n\n return {\n statusCode: 200,\n responseBody: result,\n };\n}\n\nexport async function findTaskImportStatusByRepo(\n deps: {\n logger: LoggerService;\n config: Config;\n githubApiService: GithubApiService;\n gitlabApiService: GitlabApiService;\n catalogHttpClient: CatalogHttpClient;\n repositoryDao: RepositoryDao<'repositories'>;\n taskDao: ScaffolderTaskDao;\n taskLocationsDao: TaskLocationsDao;\n discovery: DiscoveryService;\n auth: AuthService;\n },\n repoUrl: string,\n skipTasks?: boolean,\n): Promise<HandlerResponse<Components.Schemas.Import>> {\n deps.logger.debug(`Getting bulk import job status for ${repoUrl}.`);\n\n const gitUrl = gitUrlParse(repoUrl);\n\n const errors: string[] = [];\n const result: Components.Schemas.Import = {\n id: repoUrl,\n repository: {\n url: repoUrl,\n name: gitUrl.name,\n organization: gitUrl.organization,\n id: `${gitUrl.organization}/${gitUrl.name}`,\n },\n };\n try {\n const repository = await deps.repositoryDao.findRepositoryByUrl(repoUrl);\n if (!repository) {\n throw new NotFoundError(`Repository ${repoUrl} info was not found`);\n }\n\n const task = await deps.taskDao.lastExecutedTaskByRepoId(repository?.id);\n if (!task) {\n throw new NotFoundError(\n `Unable to find scaffolder task for repository: ${repository?.id}`,\n );\n }\n\n const scaffolderUrl = await deps.discovery.getBaseUrl('scaffolder');\n const { token } = await deps.auth.getPluginRequestToken({\n onBehalfOf: await deps.auth.getOwnServiceCredentials(),\n targetPluginId: 'scaffolder',\n });\n\n const response = await fetch(`${scaffolderUrl}/v2/tasks/${task.taskId}`, {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n });\n if (!skipTasks) {\n const tasks = await deps.taskDao.findTasksByRepositoryId(repository.id);\n const tasksWithLocations = await Promise.all(\n tasks.map(async taskItem => {\n const locations = await deps.taskLocationsDao.findLocationsByTaskId(\n taskItem.taskId,\n );\n const taskLocations = locations.map(location => location.location);\n return {\n ...taskItem,\n locations: taskLocations,\n };\n }),\n );\n result.tasks = tasksWithLocations;\n }\n\n result.task = { taskId: task.taskId };\n let data;\n if (response.ok) {\n data = await response.json();\n result.lastUpdate = data.lastHeartbeatAt;\n\n const approvalTool =\n repository.approvalTool as unknown as Components.Schemas.ApprovalTool;\n const pullRequest = await parsePullOrMergeRequestInfo(\n data.state?.checkpoints,\n {\n githubApiService: deps.githubApiService,\n gitlabApiService: deps.gitlabApiService,\n approvalTool,\n logger: deps.logger,\n repoUrl,\n },\n );\n if (pullRequest && approvalTool === 'GITLAB') {\n result.gitlab = { pullRequest };\n }\n if (pullRequest && approvalTool === 'GIT') {\n result.github = { pullRequest };\n }\n\n result.status =\n `TASK_${(data.status as string)?.toLocaleUpperCase()}` as Components.Schemas.TaskImportStatus;\n } else {\n const errMsg =\n (await response.text()) ??\n `Failed to fetch task ${task.taskId}. Response status: ${response.status}`;\n throw new Error(errMsg);\n }\n } catch (error: any) {\n errors.push(error.message);\n result.errors = errors;\n result.status = 'TASK_FETCH_FAILED';\n if (error.name?.includes('NotFoundError')) {\n return {\n statusCode: 404,\n responseBody: result,\n };\n }\n }\n\n return {\n statusCode: 200,\n responseBody: result,\n };\n}\n\nexport async function findOrchestratorImportStatusByRepo(\n deps: {\n logger: LoggerService;\n orchestratorRepositoryDao: RepositoryDao<'orchestrator_repositories'>;\n orchestratorWorkflowDao: OrchestratorWorkflowDao;\n discovery: DiscoveryService;\n },\n repoUrl: string,\n token: string,\n skipWorkflows?: boolean,\n): Promise<HandlerResponse<Components.Schemas.Import>> {\n deps.logger.debug(\n `Getting orchestrator workflow import job status for ${repoUrl}.`,\n );\n\n const gitUrl = gitUrlParse(repoUrl);\n\n const errors: string[] = [];\n const result: Components.Schemas.Import = {\n id: repoUrl,\n repository: {\n url: repoUrl,\n name: gitUrl.name,\n organization: gitUrl.organization,\n id: `${gitUrl.organization}/${gitUrl.name}`,\n },\n };\n try {\n const repository =\n await deps.orchestratorRepositoryDao.findRepositoryByUrl(repoUrl);\n if (repository) {\n const workflow =\n await deps.orchestratorWorkflowDao.lastExecutedWorkflowByRepoId(\n repository.id,\n );\n if (!workflow) {\n throw new NotFoundError(\n `Workflow for repository ${repoUrl} was not found`,\n );\n }\n if (workflow.instanceId) {\n const baseUrl = await deps.discovery.getBaseUrl('orchestrator');\n const orchestratorApi = new DefaultApi(new Configuration(), baseUrl);\n const response = await orchestratorApi.getInstanceById(\n workflow.instanceId,\n {\n headers: {\n Authorization: `Bearer ${token}`,\n 'Content-Type': 'application/json',\n },\n },\n );\n\n const instance = response.data;\n if (instance) {\n result.workflow = {\n workflowId: instance.id,\n };\n if (!skipWorkflows) {\n const workflows =\n await deps.orchestratorWorkflowDao.findWorkflowsByRepositoryId(\n repository.id,\n );\n result.workflows = workflows.map((w: OrchestratorWorkflow) => ({\n workflowId: w.instanceId,\n }));\n }\n\n result.approvalTool =\n repository.approvalTool as unknown as Components.Schemas.ApprovalTool;\n result.lastUpdate = instance.end;\n const status =\n `WORKFLOW_${(instance.state as string)?.toLocaleUpperCase()}` as Components.Schemas.WorkflowImportStatus;\n result.status = status;\n }\n }\n }\n } catch (error: any) {\n errors.push(error.message);\n result.errors = errors;\n result.status = 'WORKFLOW_FETCH_FAILED';\n if (error.name?.includes('NotFoundError')) {\n return {\n statusCode: 404,\n responseBody: result,\n };\n }\n }\n\n return {\n statusCode: 200,\n responseBody: result,\n };\n}\n\nasync function parsePullOrMergeRequestInfo(\n checkpoints: Record<string, any>,\n {\n githubApiService,\n gitlabApiService,\n approvalTool,\n logger,\n repoUrl,\n }: {\n githubApiService: GithubApiService;\n gitlabApiService: GitlabApiService;\n approvalTool: Components.Schemas.ApprovalTool;\n logger: LoggerService;\n repoUrl: string;\n },\n): Promise<Components.Schemas.PullRequest | undefined> {\n // return errors ?\n if (approvalTool !== 'GITLAB' && approvalTool !== 'GIT') {\n return undefined;\n }\n const gitApiService =\n approvalTool === 'GITLAB' ? gitlabApiService : githubApiService;\n\n for (const key in checkpoints) {\n if (!checkpoints.hasOwnProperty(key)) {\n continue;\n }\n try {\n if (\n key.startsWith('v1.task.checkpoint.publish.create.pr') ||\n key.startsWith('v1.task.checkpoint.publish.create.mr')\n ) {\n const url =\n checkpoints[key]?.value?.html_url ??\n checkpoints[key]?.value?.mrWebUrl;\n if (!url) {\n continue;\n }\n const prNumber = Number.parseInt(url.split('/').pop()!, 10);\n const prDetails = await gitApiService.getPullRequest(repoUrl, prNumber);\n\n let catalogInfoContent: string | undefined;\n if (prDetails.prSha) {\n catalogInfoContent = await gitApiService.getCatalogInfoFile(logger, {\n repoUrl,\n prHeadSha: prDetails.prSha,\n prNumber,\n });\n }\n return {\n url,\n number: prNumber,\n title: prDetails.title,\n body: prDetails.body,\n status: prDetails.merged ? 'PR_MERGED' : 'WAIT_PR_APPROVAL',\n catalogInfoContent,\n };\n }\n } catch (err) {\n logger.warn(`Error while processing checkpoint ${key}: ${err}`);\n continue;\n }\n }\n\n return undefined;\n}\n\nexport async function deleteImportByRepo(\n deps: {\n logger: LoggerService;\n config: Config;\n gitApiService: GitApiService;\n catalogHttpClient: CatalogHttpClient;\n },\n repoUrl: string,\n defaultBranch?: string,\n): Promise<HandlerResponse<void>> {\n deps.logger.debug(`Deleting bulk import job status for ${repoUrl}..`);\n\n // Check to see if there are any PR\n const openImportPr = await deps.gitApiService.findImportOpenPr(deps.logger, {\n repoUrl: repoUrl,\n });\n\n const gitUrl = gitUrlParse(repoUrl);\n if (openImportPr?.prUrl) {\n // Close PR\n const appTitle =\n deps.config.getOptionalString('app.title') ?? 'Red Hat Developer Hub';\n const appBaseUrl = deps.config.getString('app.baseUrl');\n\n await deps.gitApiService.closeImportPR(deps.logger, {\n repoUrl,\n gitUrl,\n comment: `Closing PR upon request for bulk import deletion. This request was created from [${appTitle}](${appBaseUrl}).`,\n });\n }\n // Also delete the import branch, so that it is not outdated if we try later to import the repo again\n await deps.gitApiService.deleteImportBranch({\n repoUrl,\n gitUrl,\n });\n // Remove Location from catalog\n const catalogUrl = getCatalogUrl(deps.config, repoUrl, defaultBranch);\n const findLocationFrom = (list: { id?: string; target: string }[]) => {\n for (const loc of list) {\n if (loc.target === catalogUrl) {\n return loc.id;\n }\n }\n return undefined;\n };\n\n const locationId = findLocationFrom(\n (\n await deps.catalogHttpClient.listCatalogUrlLocationsByIdFromLocationsEndpoint()\n ).locations,\n );\n if (locationId) {\n await deps.catalogHttpClient.deleteCatalogLocationById(locationId);\n }\n\n return {\n statusCode: 204,\n responseBody: undefined,\n };\n}\n\nexport async function deleteRepositoryRecord<\n DAO extends RepositoryDao<RepositoryName>,\n>(\n deps: {\n logger: LoggerService;\n dao: DAO;\n },\n repoUrl: string,\n): Promise<HandlerResponse<void>> {\n deps.logger.debug(`Deleting repository from database by name ${repoUrl}...`);\n try {\n await deps.dao.deleteRepository(repoUrl);\n\n return {\n statusCode: 204,\n responseBody: undefined,\n };\n } catch (error: any) {\n deps.logger.error(\n `Failed to delete repository from database by url ${repoUrl}`,\n error,\n );\n return {\n statusCode: 500,\n };\n }\n}\n"],"names":["DefaultSortColumn","DefaultSortOrder","getNestedValue","DefaultPageNumber","DefaultPageSize","getCatalogFilename","parseGitURLForApprovalTool","imports","paginateArray","logErrorIfNeeded","getCatalogUrl","gitUrlParse","errors","NotFoundError","DefaultApi","Configuration"],"mappings":"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"}
|
|
@@ -2,11 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
var rootHttpRouter = require('@backstage/backend-defaults/rootHttpRouter');
|
|
4
4
|
var errors = require('@backstage/errors');
|
|
5
|
-
var pluginPermissionNode = require('@backstage/plugin-permission-node');
|
|
6
5
|
var formats = require('ajv-formats/dist/formats');
|
|
7
6
|
var express = require('express');
|
|
8
7
|
var openapiBackend = require('openapi-backend');
|
|
9
|
-
var backstagePluginBulkImportCommon = require('@red-hat-developer-hub/backstage-plugin-bulk-import-common');
|
|
10
8
|
var catalogHttpClient = require('../catalog/catalogHttpClient.cjs.js');
|
|
11
9
|
var catalogInfoGenerator = require('../catalog/catalogInfoGenerator.cjs.js');
|
|
12
10
|
var migration = require('../database/migration.cjs.js');
|
|
@@ -88,7 +86,7 @@ async function createRouter(options) {
|
|
|
88
86
|
config,
|
|
89
87
|
cache,
|
|
90
88
|
discovery,
|
|
91
|
-
|
|
89
|
+
catalog,
|
|
92
90
|
auditor,
|
|
93
91
|
database
|
|
94
92
|
} = options;
|
|
@@ -107,9 +105,8 @@ async function createRouter(options) {
|
|
|
107
105
|
const catalogHttpClient$1 = new catalogHttpClient.CatalogHttpClient({
|
|
108
106
|
logger,
|
|
109
107
|
config,
|
|
110
|
-
discovery,
|
|
111
108
|
auth: auth$1,
|
|
112
|
-
|
|
109
|
+
catalog
|
|
113
110
|
});
|
|
114
111
|
const catalogInfoGenerator$1 = new catalogInfoGenerator.CatalogInfoGenerator(
|
|
115
112
|
logger,
|
|
@@ -381,7 +378,6 @@ async function createRouter(options) {
|
|
|
381
378
|
logger,
|
|
382
379
|
config,
|
|
383
380
|
auth: auth$1,
|
|
384
|
-
catalogApi,
|
|
385
381
|
gitlabApiService: gitlabApiService$1,
|
|
386
382
|
githubApiService: githubApiService$1,
|
|
387
383
|
catalogInfoGenerator: catalogInfoGenerator$1,
|
|
@@ -576,10 +572,6 @@ async function createRouter(options) {
|
|
|
576
572
|
);
|
|
577
573
|
const router = express.Router();
|
|
578
574
|
router.use(express__default.default.json());
|
|
579
|
-
const permissionIntegrationRouter = pluginPermissionNode.createPermissionIntegrationRouter({
|
|
580
|
-
permissions: [backstagePluginBulkImportCommon.bulkImportPermission]
|
|
581
|
-
});
|
|
582
|
-
router.use(permissionIntegrationRouter);
|
|
583
575
|
router.use((req, res, next) => {
|
|
584
576
|
const raw = req.headers["x-scm-tokens"];
|
|
585
577
|
const rawStr = Array.isArray(raw) ? raw[0] : raw;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"router.cjs.js","sources":["../../src/service/router.ts"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\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 { MiddlewareFactory } from '@backstage/backend-defaults/rootHttpRouter';\nimport type {\n AuditorService,\n AuditorServiceEvent,\n AuthService,\n CacheService,\n DatabaseService,\n DiscoveryService,\n HttpAuthService,\n LoggerService,\n} from '@backstage/backend-plugin-api';\nimport type { CatalogApi } from '@backstage/catalog-client';\nimport type { Config } from '@backstage/config';\nimport { InputError } from '@backstage/errors';\nimport type { PermissionEvaluator } from '@backstage/plugin-permission-common';\nimport { createPermissionIntegrationRouter } from '@backstage/plugin-permission-node';\n\nimport { fullFormats } from 'ajv-formats/dist/formats';\nimport express, { Router, type Request, type Response } from 'express';\nimport {\n Document,\n OpenAPIBackend,\n type Context,\n type Request as OpenAPIRequest,\n} from 'openapi-backend';\n\nimport { bulkImportPermission } from '@red-hat-developer-hub/backstage-plugin-bulk-import-common';\n\nimport { CatalogHttpClient } from '../catalog/catalogHttpClient';\nimport { CatalogInfoGenerator } from '../catalog/catalogInfoGenerator';\nimport { migrate } from '../database/migration';\nimport {\n OrchestratorWorkflowDao,\n RepositoryDao,\n ScaffolderTaskDao,\n TaskLocationsDao,\n} from '../database/repositoryDao';\nimport type { Components, Paths, SourceImport } from '../generated/openapi.d';\nimport { openApiDocument } from '../generated/openapidocument';\nimport { GithubApiService } from '../github';\nimport { GitlabApiService } from '../gitlab';\nimport {\n getImportTemplateRef,\n parseGitURLForApprovalTool,\n permissionCheck,\n} from '../helpers';\nimport { auditCreateEvent } from '../helpers/auditorUtils';\nimport {\n createImportJobs,\n deleteImportByRepo,\n deleteRepositoryRecord,\n findAllImports,\n findImportStatusByRepo,\n findOrchestratorImportStatusByRepo,\n findTaskImportStatusByRepo,\n sortImports,\n} from './handlers/import';\nimport { createWorkflowImportJobs } from './handlers/import/execute-orchestrator-workflow';\nimport { createTaskImportJobs } from './handlers/import/execute-template';\nimport { findAllOrganizations } from './handlers/organization';\nimport { ping } from './handlers/ping';\nimport {\n findAllRepositories,\n findRepositoriesByOrganization,\n} from './handlers/repository';\nimport { findAllSCMHosts } from './handlers/scm/scm';\n\n/**\n * Router Options\n * @public\n */\nexport interface RouterOptions {\n logger: LoggerService;\n permissions: PermissionEvaluator;\n config: Config;\n cache: CacheService;\n discovery: DiscoveryService;\n httpAuth: HttpAuthService;\n auth: AuthService;\n catalogApi: CatalogApi;\n auditor: AuditorService;\n database: DatabaseService;\n}\n\nnamespace Operations {\n export const PING = 'ping';\n export const FIND_ALL_SCM_HOSTS = 'findAllSCMHosts';\n export const FIND_ALL_ORGANIZATIONS = 'findAllOrganizations';\n export const FIND_ALL_REPOSITORIES = 'findAllRepositories';\n\n export const FIND_REPOSITORIES_BY_ORGANIZATION =\n 'findRepositoriesByOrganization';\n\n export const FIND_ALL_IMPORTS = 'findAllImports';\n export const FIND_ALL_TASK_IMPORTS = 'findAllTaskImports';\n export const FIND_ALL_ORCHESTRATOR_WORKFLOW_IMPORTS =\n 'findAllOrchestratorWorkflowImports';\n\n export const CREATE_IMPORT_JOBS = 'createImportJobs';\n export const CREATE_TASK_IMPORT_JOBS = 'createTaskImportJobs';\n export const CREATE_ORCHESTRATOR_WORKFLOW_JOBS =\n 'createOrchestratorWorkflowJobs';\n\n export const FIND_IMPORT_STATUS_BY_REPO = 'findImportStatusByRepo';\n export const FIND_TASK_IMPORT_STATUS_BY_REPO = 'findTaskImportStatusByRepo';\n export const FIND_ORCHESTRATOR_IMPORT_STATUS_BY_REPO =\n 'findOrchestratorImportStatusByRepo';\n\n export const DELETE_IMPORT_BY_REPO = 'deleteImportByRepo';\n export const DELETE_TASK_IMPORT_BY_REPO = 'deleteTaskImportByRepo';\n export const DELETE_ORCHESTRATOR_IMPORT_BY_REPO =\n 'deleteOrchestratorImportByRepo';\n}\n\nconst SCM_TOKENS_MAX_BYTES = 4096;\n\nconst isValidTokenMap = (v: unknown): v is Record<string, string> =>\n typeof v === 'object' &&\n v !== null &&\n Object.values(v).every(val => typeof val === 'string' && val.length > 0);\n\nfunction parseScmTokensHeader(\n rawTokenHeader: string | undefined,\n logger: LoggerService,\n): Record<string, string> | undefined {\n let token: Record<string, string> | undefined;\n if (!rawTokenHeader) return undefined;\n if (rawTokenHeader.length > SCM_TOKENS_MAX_BYTES) {\n logger.warn('x-scm-tokens header exceeds maximum allowed size; ignoring');\n return undefined;\n }\n try {\n token = JSON.parse(rawTokenHeader) as Record<string, string>;\n if (typeof token !== 'object' || token === null || Array.isArray(token)) {\n throw new Error('x-scm-tokens must be a JSON object');\n }\n } catch (e) {\n throw new InputError(\n `Invalid x-scm-tokens header: ${(e as Error).message}`,\n );\n }\n\n if (!isValidTokenMap(token)) {\n throw new InputError(\n 'Invalid x-scm-tokens header: all values must be non-empty strings',\n );\n }\n return token;\n}\n\n/**\n * Router\n * @public\n */\nexport async function createRouter(\n options: RouterOptions,\n): Promise<express.Router> {\n const {\n logger,\n httpAuth,\n auth,\n permissions,\n config,\n cache,\n discovery,\n catalogApi,\n auditor: auditor,\n database,\n } = options;\n\n const knex = await migrate(database);\n const repositoryDao = new RepositoryDao(knex, logger, 'repositories');\n const taskDao = new ScaffolderTaskDao(knex);\n const taskLocationsDao = new TaskLocationsDao(knex);\n const orchestratorRepositoryDao = new RepositoryDao(\n knex,\n logger,\n 'orchestrator_repositories',\n );\n const orchestratorWorkflowDao = new OrchestratorWorkflowDao(knex);\n // GitHub and GitLab both implement the GitApiService interface; the router\n // selects the appropriate service per request based on approvalTool.\n const githubApiService = new GithubApiService(logger, config, cache);\n const gitlabApiService = new GitlabApiService(logger, config, cache);\n const catalogHttpClient = new CatalogHttpClient({\n logger,\n config,\n discovery,\n auth,\n catalogApi,\n });\n const catalogInfoGenerator = new CatalogInfoGenerator(\n logger,\n catalogHttpClient,\n );\n\n // create openapi requests handler\n const api = new OpenAPIBackend({\n ajvOpts: {\n verbose: true,\n formats: fullFormats, // open issue: https://github.com/openapistack/openapi-backend/issues/280\n },\n validate: true,\n definition: openApiDocument,\n handlers: {\n validationFail: async (c, _req: Request, res: Response) =>\n res.status(400).json({ err: c.validation.errors }),\n notFound: async (_c, req: Request, res: Response) =>\n res.status(404).json({ err: `'${req.method} ${req.path}' not found` }),\n notImplemented: async (_c, req: Request, res: Response) =>\n res\n .status(500)\n .json({ err: `'${req.method} ${req.path}' not implemented` }),\n },\n });\n\n const templateRef = config.getOptionalString('bulkImport.importTemplate');\n let finalTemplateRef: string | undefined;\n if (templateRef) {\n finalTemplateRef = getImportTemplateRef(templateRef);\n }\n\n const orchestratorWorkflowId = config.getOptionalString(\n 'bulkImport.orchestratorWorkflow',\n );\n\n await api.init();\n\n api.register(\n Operations.PING,\n async (_c: Context, _req: Request, res: Response) => {\n const result = await ping(logger);\n return res.status(result.statusCode).json(result.responseBody);\n },\n );\n\n api.register(\n Operations.FIND_ALL_SCM_HOSTS,\n async (_c: Context, _req: Request, res: Response) => {\n const result = await findAllSCMHosts(config);\n return res.status(result.statusCode).json(result.responseBody);\n },\n );\n\n api.register(\n Operations.FIND_ALL_ORGANIZATIONS,\n async (c: Context, _req: Request, res: Response) => {\n const q: Paths.FindAllOrganizations.QueryParameters = {\n ...c.request.query,\n };\n // we need to convert strings to real types due to open PR https://github.com/openapistack/openapi-backend/pull/571\n q.pagePerIntegration = stringToNumber(q.pagePerIntegration);\n q.sizePerIntegration = stringToNumber(q.sizePerIntegration);\n const response = await findAllOrganizations(\n logger,\n q.approvalTool === 'GITLAB' ? gitlabApiService : githubApiService,\n q.search,\n q.pagePerIntegration,\n q.sizePerIntegration,\n );\n return res.status(response.statusCode).json({\n errors: response.responseBody?.errors,\n organizations: response.responseBody?.organizations,\n totalCount: response.responseBody?.totalCount,\n pagePerIntegration: response.responseBody?.pagePerIntegration,\n sizePerIntegration: response.responseBody?.sizePerIntegration,\n approvalTool: q.approvalTool,\n } as Components.Schemas.OrganizationList);\n },\n );\n\n api.register(\n Operations.FIND_ALL_REPOSITORIES,\n async (c: Context, _req: Request, res: Response) => {\n const q: Paths.FindAllRepositories.QueryParameters = {\n ...c.request.query,\n };\n // we need to convert strings to real types due to open PR https://github.com/openapistack/openapi-backend/pull/571\n q.pagePerIntegration = stringToNumber(q.pagePerIntegration);\n q.sizePerIntegration = stringToNumber(q.sizePerIntegration);\n q.checkImportStatus = stringToBoolean(q.checkImportStatus);\n\n const userTokens = res.locals.scmTokens as\n | Record<string, string>\n | undefined;\n\n if (!userTokens || Object.keys(userTokens).length === 0) {\n return res.status(401).json({\n error:\n 'User SCM credentials are required to list repositories. Ensure the SCM OAuth integration is configured.',\n });\n }\n\n const response = await findAllRepositories(\n {\n logger,\n config,\n gitApiService:\n q.approvalTool === 'GITLAB' ? gitlabApiService : githubApiService,\n catalogHttpClient,\n },\n {\n search: q.search,\n checkStatus: q.checkImportStatus,\n pageNumber: q.pagePerIntegration,\n pageSize: q.sizePerIntegration,\n userTokens,\n },\n );\n const repos = response.responseBody?.repositories;\n return res.status(response.statusCode).json({\n errors: response.responseBody?.errors,\n repositories: repos,\n totalCount: response.responseBody?.totalCount,\n pagePerIntegration: q.pagePerIntegration,\n sizePerIntegration: q.sizePerIntegration,\n approvalTool: q.approvalTool,\n } as Components.Schemas.RepositoryList);\n },\n );\n\n api.register(\n Operations.FIND_REPOSITORIES_BY_ORGANIZATION,\n async (c: Context, _req: Request, res: Response) => {\n const q: Paths.FindRepositoriesByOrganization.QueryParameters = {\n ...c.request.query,\n };\n // we need to convert strings to real types due to open PR https://github.com/openapistack/openapi-backend/pull/571\n q.pagePerIntegration = stringToNumber(q.pagePerIntegration);\n q.sizePerIntegration = stringToNumber(q.sizePerIntegration);\n q.checkImportStatus = stringToBoolean(q.checkImportStatus);\n\n const userTokens = res.locals.scmTokens as\n | Record<string, string>\n | undefined;\n\n if (!userTokens || Object.keys(userTokens).length === 0) {\n return res.status(401).json({\n error:\n 'User SCM credentials are required to list repositories. Ensure the SCM OAuth integration is configured.',\n });\n }\n\n const response = await findRepositoriesByOrganization(\n {\n logger,\n config,\n gitApiService:\n q.approvalTool === 'GITLAB' ? gitlabApiService : githubApiService,\n catalogHttpClient,\n },\n c.request.params.organizationName?.toString(),\n q.search,\n q.checkImportStatus,\n q.pagePerIntegration,\n q.sizePerIntegration,\n userTokens,\n );\n const repos = response.responseBody?.repositories;\n return res.status(response.statusCode).json({\n errors: response.responseBody?.errors,\n repositories: repos,\n totalCount: response.responseBody?.totalCount,\n pagePerIntegration: q.pagePerIntegration,\n sizePerIntegration: q.sizePerIntegration,\n approvalTool: q.approvalTool,\n } as Components.Schemas.RepositoryList);\n },\n );\n\n api.register(\n Operations.FIND_ALL_IMPORTS,\n async (c: Context, _req: Request, res: Response) => {\n const {\n pageNumber,\n pageSize,\n apiVersion,\n search,\n sortColumn,\n sortOrder,\n } = getFindImportsParams(c);\n const response = await findAllImports(\n {\n logger,\n config,\n githubApiService,\n gitlabApiService,\n catalogHttpClient,\n },\n {\n apiVersion,\n },\n {\n search,\n pageNumber,\n pageSize,\n sortColumn,\n sortOrder,\n },\n );\n return res.status(response.statusCode).json(response.responseBody);\n },\n );\n api.register(\n Operations.FIND_ALL_TASK_IMPORTS,\n async (c: Context, _req: Request, res: Response) => {\n const { pageNumber, pageSize, search, sortColumn, sortOrder } =\n getFindImportsParams(c);\n const imports: SourceImport[] = [];\n const repositories = await repositoryDao.findRepositories(\n pageNumber,\n pageSize,\n search,\n );\n\n for (const repo of repositories.data) {\n const response = await findTaskImportStatusByRepo(\n {\n logger,\n config,\n githubApiService,\n gitlabApiService,\n catalogHttpClient,\n repositoryDao,\n taskDao,\n taskLocationsDao,\n discovery,\n auth,\n },\n repo.url,\n true,\n );\n if (response.responseBody) {\n imports.push(response.responseBody);\n }\n }\n\n sortImports(imports, sortColumn, sortOrder);\n\n const responseBody: Components.Schemas.ImportJobListV2 = {\n imports,\n totalCount: repositories.total,\n page: pageNumber || 1,\n size: pageSize || 5,\n };\n\n return res.status(200).json(responseBody);\n },\n );\n\n api.register(\n Operations.FIND_ALL_ORCHESTRATOR_WORKFLOW_IMPORTS,\n async (c: Context, req: Request, res: Response) => {\n const { pageNumber, pageSize, search, sortColumn, sortOrder } =\n getFindImportsParams(c);\n const imports: SourceImport[] = [];\n const repositories = await orchestratorRepositoryDao.findRepositories(\n pageNumber,\n pageSize,\n search,\n );\n\n const token = getBearerTokenFromReq(req);\n\n for (const repo of repositories.data) {\n const response = await findOrchestratorImportStatusByRepo(\n {\n logger,\n orchestratorRepositoryDao,\n orchestratorWorkflowDao,\n discovery,\n },\n repo.url,\n token,\n true,\n );\n if (response.responseBody) {\n imports.push(response.responseBody);\n }\n }\n\n sortImports(imports, sortColumn, sortOrder);\n\n const responseBody: Components.Schemas.ImportJobListV2 = {\n imports,\n totalCount: repositories.total,\n page: pageNumber || 1,\n size: pageSize || 5,\n };\n\n return res.status(200).json(responseBody);\n },\n );\n\n api.register(\n Operations.CREATE_IMPORT_JOBS,\n async (\n c: Context<Paths.CreateImportJobs.RequestBody>,\n _req: Request,\n res: Response,\n ) => {\n const q: Paths.CreateImportJobs.QueryParameters = {\n ...c.request.query,\n };\n q.dryRun = stringToBoolean(q.dryRun);\n const response = await createImportJobs(\n {\n logger,\n config,\n auth,\n catalogApi,\n gitlabApiService,\n githubApiService,\n catalogInfoGenerator,\n catalogHttpClient,\n },\n {\n importRequests: c.request.requestBody,\n dryRun: q.dryRun,\n },\n );\n return res.status(response.statusCode).json(response.responseBody);\n },\n );\n\n api.register(\n Operations.CREATE_TASK_IMPORT_JOBS,\n async (\n c: Context<Paths.CreateImportJobs.RequestBody>,\n _req: Request,\n res: Response,\n ) => {\n if (!finalTemplateRef) {\n throw new Error(\n `Missing required config value: 'bulkImport.importTemplate'`,\n );\n }\n const response = await createTaskImportJobs(\n finalTemplateRef,\n discovery,\n logger,\n auth,\n config,\n repositoryDao,\n taskDao,\n taskLocationsDao,\n c.request.requestBody,\n githubApiService,\n );\n\n return res.status(response.statusCode).json(response.responseBody);\n },\n );\n\n api.register(\n Operations.CREATE_ORCHESTRATOR_WORKFLOW_JOBS,\n async (\n c: Context<Paths.CreateImportJobs.RequestBody>,\n req: Request,\n res: Response,\n ) => {\n if (!orchestratorWorkflowId) {\n throw new Error(\n `Missing required config value: 'bulkImport.orchestratorWorkflow'`,\n );\n }\n\n const token = getBearerTokenFromReq(req);\n\n const response = await createWorkflowImportJobs({\n orchestratorWorkflowId,\n discovery,\n token,\n requestBody: c.request.requestBody,\n orchestratorWorkflowDao,\n orchestratorRepositoryDao,\n githubApiService,\n gitlabApiService,\n });\n\n res.status(response.statusCode).json(response.responseBody);\n },\n );\n\n api.register(\n Operations.FIND_TASK_IMPORT_STATUS_BY_REPO,\n async (c: Context, _req: Request, res: Response) => {\n const q: Paths.FindImportStatusByRepo.QueryParameters = {\n ...c.request.query,\n };\n if (!q.repo?.trim()) {\n throw new Error('missing or blank parameter');\n }\n const response = await findTaskImportStatusByRepo(\n {\n logger,\n config,\n githubApiService,\n gitlabApiService,\n catalogHttpClient,\n repositoryDao,\n taskDao,\n taskLocationsDao,\n discovery,\n auth,\n },\n q.repo,\n );\n return res.status(response.statusCode).json(response.responseBody);\n },\n );\n\n api.register(\n Operations.FIND_IMPORT_STATUS_BY_REPO,\n async (c: Context, _req: Request, res: Response) => {\n const q: Paths.FindImportStatusByRepo.QueryParameters = {\n ...c.request.query,\n };\n if (!q.repo?.trim()) {\n throw new Error('missing or blank parameter');\n }\n const response = await findImportStatusByRepo(\n {\n logger,\n config,\n gitApiService:\n q.approvalTool === 'GITLAB' ? gitlabApiService : githubApiService,\n catalogHttpClient,\n approvalTool: q.approvalTool,\n },\n q.repo,\n q.defaultBranch,\n true,\n );\n return res.status(response.statusCode).json(response.responseBody);\n },\n );\n\n api.register(\n Operations.FIND_ORCHESTRATOR_IMPORT_STATUS_BY_REPO,\n async (c: Context, req: Request, res: Response) => {\n const q: Paths.FindImportStatusByRepo.QueryParameters = {\n ...c.request.query,\n };\n if (!q.repo?.trim()) {\n throw new Error('missing or blank parameter');\n }\n const token = getBearerTokenFromReq(req);\n const response = await findOrchestratorImportStatusByRepo(\n {\n logger,\n orchestratorRepositoryDao,\n orchestratorWorkflowDao,\n discovery,\n },\n q.repo,\n token,\n );\n return res.status(response.statusCode).json(response.responseBody);\n },\n );\n\n api.register(\n Operations.DELETE_TASK_IMPORT_BY_REPO,\n async (c: Context, _req: Request, res: Response) => {\n const q: Paths.DeleteImportByRepo.QueryParameters = {\n ...c.request.query,\n };\n if (!q.repo?.trim()) {\n throw new Error('missing or blank \"repo\" parameter');\n }\n const response = await deleteRepositoryRecord(\n {\n logger,\n dao: repositoryDao,\n },\n q.repo,\n );\n return res.status(response.statusCode).json(response.responseBody);\n },\n );\n\n api.register(\n Operations.DELETE_IMPORT_BY_REPO,\n async (c: Context, _req: Request, res: Response) => {\n const q: Paths.DeleteImportByRepo.QueryParameters = {\n ...c.request.query,\n };\n if (!q.repo?.trim()) {\n throw new Error('missing or blank \"repo\" parameter');\n }\n const response = await deleteImportByRepo(\n {\n logger,\n config,\n gitApiService:\n parseGitURLForApprovalTool(q.repo) === 'GITLAB'\n ? gitlabApiService\n : githubApiService,\n catalogHttpClient,\n },\n q.repo,\n q.defaultBranch,\n );\n return res.status(response.statusCode).json(response.responseBody);\n },\n );\n\n api.register(\n Operations.DELETE_ORCHESTRATOR_IMPORT_BY_REPO,\n async (c: Context, _req: Request, res: Response) => {\n const q: Paths.DeleteImportByRepo.QueryParameters = {\n ...c.request.query,\n };\n if (!q.repo?.trim()) {\n throw new Error('missing or blank \"repo\" parameter');\n }\n const response = await deleteRepositoryRecord(\n {\n logger,\n dao: orchestratorRepositoryDao,\n },\n q.repo,\n );\n return res.status(response.statusCode).json(response.responseBody);\n },\n );\n\n const router = Router();\n router.use(express.json());\n\n const permissionIntegrationRouter = createPermissionIntegrationRouter({\n permissions: [bulkImportPermission],\n });\n router.use(permissionIntegrationRouter);\n\n // Strip x-scm-tokens from req.headers before the permission check and audit\n // middleware run so that OAuth tokens are never captured in audit logs.\n // The parsed map is stored in res.locals.scmTokens for handler use.\n router.use((req, res, next) => {\n const raw = req.headers['x-scm-tokens'];\n const rawStr = Array.isArray(raw) ? raw[0] : raw;\n delete req.headers['x-scm-tokens'];\n if (rawStr) {\n try {\n res.locals.scmTokens = parseScmTokensHeader(rawStr, logger);\n } catch (e) {\n next(e);\n return;\n }\n }\n next();\n });\n\n router.use(async (req, _res, next) => {\n if (req.path !== '/ping') {\n try {\n await permissionCheck(\n auditor,\n api.matchOperation(req as OpenAPIRequest)?.operationId,\n permissions,\n httpAuth,\n req,\n );\n } catch (e) {\n next(e);\n return;\n }\n }\n next();\n });\n\n router.use(async (req, res, next) => {\n const reqCast = req as OpenAPIRequest;\n const operationId = api.matchOperation(reqCast)?.operationId;\n\n const auditorEvent = await createAuditorEventByOperationId(\n operationId,\n req,\n auditor,\n );\n try {\n const response = (await api.handleRequest(reqCast, req, res)) as Response;\n auditorEvent?.success({ meta: { responseStatus: response.statusCode } });\n next();\n } catch (err: any) {\n auditorEvent?.fail({ error: err, meta: { responseStatus: 500 } });\n next(err);\n }\n });\n\n const middleware = MiddlewareFactory.create({ logger, config });\n router.use(middleware.error());\n\n return router;\n}\n\nasync function createAuditorEventByOperationId(\n operationId: string | undefined,\n req: Request,\n auditor: AuditorService,\n): Promise<AuditorServiceEvent | undefined> {\n let auditorEvent;\n switch (operationId) {\n case Operations.PING:\n auditorEvent = await auditCreateEvent(auditor, 'ping', req);\n break;\n case Operations.FIND_ALL_SCM_HOSTS:\n auditorEvent = await auditCreateEvent(auditor, 'scm-hosts-read', req);\n break;\n\n case Operations.FIND_ALL_ORGANIZATIONS:\n auditorEvent = await auditCreateEvent(auditor, 'org-read', req, {\n queryType: req.query.search ? 'by-query' : 'all',\n search: req.query?.search,\n });\n break;\n case Operations.FIND_ALL_REPOSITORIES:\n auditorEvent = await auditCreateEvent(auditor, 'repo-read', req, {\n queryType: req.query.search ? 'by-query' : 'all',\n search: req.query.search,\n });\n break;\n case Operations.FIND_REPOSITORIES_BY_ORGANIZATION: {\n const organizationName = req.params.organizationName?.toString();\n auditorEvent = await auditCreateEvent(auditor, 'repo-read', req, {\n queryType: 'by-org',\n organizationName,\n });\n break;\n }\n case Operations.FIND_ALL_IMPORTS:\n case Operations.FIND_ALL_TASK_IMPORTS:\n case Operations.FIND_ALL_ORCHESTRATOR_WORKFLOW_IMPORTS:\n auditorEvent = await auditCreateEvent(auditor, 'import-read', req, {\n queryType: req.query.search ? 'by-query' : 'all',\n search: req.query.search,\n });\n break;\n case Operations.CREATE_IMPORT_JOBS:\n case Operations.CREATE_TASK_IMPORT_JOBS:\n case Operations.CREATE_ORCHESTRATOR_WORKFLOW_JOBS:\n auditorEvent = await auditCreateEvent(auditor, 'import-write', req, {\n actionType: 'create',\n });\n break;\n case Operations.FIND_IMPORT_STATUS_BY_REPO:\n case Operations.FIND_TASK_IMPORT_STATUS_BY_REPO:\n case Operations.FIND_ORCHESTRATOR_IMPORT_STATUS_BY_REPO:\n auditorEvent = await auditCreateEvent(\n auditor,\n 'import-status-read',\n req,\n { queryType: 'by-query', repo: req.query.repo },\n );\n break;\n case Operations.DELETE_IMPORT_BY_REPO:\n case Operations.DELETE_TASK_IMPORT_BY_REPO:\n case Operations.DELETE_ORCHESTRATOR_IMPORT_BY_REPO:\n auditorEvent = await auditCreateEvent(auditor, 'import-write', req, {\n actionType: 'delete',\n repository: req.query.repo,\n });\n break;\n case undefined:\n auditorEvent = await auditCreateEvent(auditor, operationId, req);\n break;\n default:\n // do nothing\n break;\n }\n return auditorEvent;\n}\n\nfunction stringToNumber(s: number | undefined): number | undefined {\n return s ? Number.parseInt(s.toString(), 10) : undefined;\n}\n\nfunction stringToBoolean(s: boolean | undefined): boolean | undefined {\n if (!s) {\n return undefined;\n }\n return s.toString() === 'true';\n}\nfunction getFindImportsParams(c: Context<any, any, any, any, any, Document>): {\n pageNumber?: number;\n pageSize?: number;\n apiVersion?: Paths.FindAllImports.Parameters.ApiVersion;\n search?: string;\n sortColumn?: Components.Parameters.SortColumnQueryParam;\n sortOrder?: Components.Parameters.SortOrderQueryParam;\n} {\n const h: Paths.FindAllImports.HeaderParameters = {\n ...c.request.headers,\n };\n const apiVersion = h['api-version'];\n const q: Paths.FindAllImports.QueryParameters = {\n ...c.request.query,\n };\n // we need to convert strings to real types due to open PR https://github.com/openapistack/openapi-backend/pull/571\n let pageNumber: number | undefined;\n let pageSize: number | undefined;\n if (apiVersion === undefined || apiVersion === 'v1') {\n // pagePerIntegration and sizePerIntegration deprecated in v1. 'page' and 'size' take precedence.\n pageNumber = stringToNumber(q.page || q.pagePerIntegration);\n pageSize = stringToNumber(q.size || q.sizePerIntegration);\n } else {\n // pagePerIntegration and sizePerIntegration removed in v2+ and replaced by 'page' and 'size'.\n pageNumber = stringToNumber(q.page);\n pageSize = stringToNumber(q.size);\n }\n return {\n pageNumber,\n pageSize,\n apiVersion: apiVersion,\n search: q.search,\n sortColumn: q.sortColumn,\n sortOrder: q.sortOrder,\n };\n}\n\nfunction getBearerTokenFromReq(req: express.Request): string {\n const header = req.header('authorization') ?? req.headers.authorization;\n if (header?.startsWith(`Bearer `)) {\n return header.replace('Bearer ', '');\n }\n throw new InputError(`Request provided without token`);\n}\n"],"names":["Operations","InputError","auth","migrate","repositoryDao","RepositoryDao","ScaffolderTaskDao","TaskLocationsDao","OrchestratorWorkflowDao","githubApiService","GithubApiService","gitlabApiService","GitlabApiService","catalogHttpClient","CatalogHttpClient","catalogInfoGenerator","CatalogInfoGenerator","OpenAPIBackend","fullFormats","openApiDocument","getImportTemplateRef","ping","findAllSCMHosts","findAllOrganizations","findAllRepositories","findRepositoriesByOrganization","findAllImports","findTaskImportStatusByRepo","sortImports","findOrchestratorImportStatusByRepo","createImportJobs","createTaskImportJobs","createWorkflowImportJobs","findImportStatusByRepo","deleteRepositoryRecord","deleteImportByRepo","parseGitURLForApprovalTool","Router","express","createPermissionIntegrationRouter","bulkImportPermission","permissionCheck","MiddlewareFactory","auditCreateEvent"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"router.cjs.js","sources":["../../src/service/router.ts"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\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 { MiddlewareFactory } from '@backstage/backend-defaults/rootHttpRouter';\nimport type {\n AuditorService,\n AuditorServiceEvent,\n AuthService,\n CacheService,\n DatabaseService,\n DiscoveryService,\n HttpAuthService,\n LoggerService,\n} from '@backstage/backend-plugin-api';\nimport type { Config } from '@backstage/config';\nimport { InputError } from '@backstage/errors';\nimport type { CatalogService } from '@backstage/plugin-catalog-node';\nimport type { PermissionEvaluator } from '@backstage/plugin-permission-common';\n\nimport { fullFormats } from 'ajv-formats/dist/formats';\nimport express, { Router, type Request, type Response } from 'express';\nimport {\n Document,\n OpenAPIBackend,\n type Context,\n type Request as OpenAPIRequest,\n} from 'openapi-backend';\n\nimport { CatalogHttpClient } from '../catalog/catalogHttpClient';\nimport { CatalogInfoGenerator } from '../catalog/catalogInfoGenerator';\nimport { migrate } from '../database/migration';\nimport {\n OrchestratorWorkflowDao,\n RepositoryDao,\n ScaffolderTaskDao,\n TaskLocationsDao,\n} from '../database/repositoryDao';\nimport type { Components, Paths, SourceImport } from '../generated/openapi.d';\nimport { openApiDocument } from '../generated/openapidocument';\nimport { GithubApiService } from '../github';\nimport { GitlabApiService } from '../gitlab';\nimport {\n getImportTemplateRef,\n parseGitURLForApprovalTool,\n permissionCheck,\n} from '../helpers';\nimport { auditCreateEvent } from '../helpers/auditorUtils';\nimport {\n createImportJobs,\n deleteImportByRepo,\n deleteRepositoryRecord,\n findAllImports,\n findImportStatusByRepo,\n findOrchestratorImportStatusByRepo,\n findTaskImportStatusByRepo,\n sortImports,\n} from './handlers/import';\nimport { createWorkflowImportJobs } from './handlers/import/execute-orchestrator-workflow';\nimport { createTaskImportJobs } from './handlers/import/execute-template';\nimport { findAllOrganizations } from './handlers/organization';\nimport { ping } from './handlers/ping';\nimport {\n findAllRepositories,\n findRepositoriesByOrganization,\n} from './handlers/repository';\nimport { findAllSCMHosts } from './handlers/scm/scm';\n\n/**\n * Router Options\n * @public\n */\nexport interface RouterOptions {\n logger: LoggerService;\n permissions: PermissionEvaluator;\n config: Config;\n cache: CacheService;\n discovery: DiscoveryService;\n httpAuth: HttpAuthService;\n auth: AuthService;\n catalog: CatalogService;\n auditor: AuditorService;\n database: DatabaseService;\n}\n\nnamespace Operations {\n export const PING = 'ping';\n export const FIND_ALL_SCM_HOSTS = 'findAllSCMHosts';\n export const FIND_ALL_ORGANIZATIONS = 'findAllOrganizations';\n export const FIND_ALL_REPOSITORIES = 'findAllRepositories';\n\n export const FIND_REPOSITORIES_BY_ORGANIZATION =\n 'findRepositoriesByOrganization';\n\n export const FIND_ALL_IMPORTS = 'findAllImports';\n export const FIND_ALL_TASK_IMPORTS = 'findAllTaskImports';\n export const FIND_ALL_ORCHESTRATOR_WORKFLOW_IMPORTS =\n 'findAllOrchestratorWorkflowImports';\n\n export const CREATE_IMPORT_JOBS = 'createImportJobs';\n export const CREATE_TASK_IMPORT_JOBS = 'createTaskImportJobs';\n export const CREATE_ORCHESTRATOR_WORKFLOW_JOBS =\n 'createOrchestratorWorkflowJobs';\n\n export const FIND_IMPORT_STATUS_BY_REPO = 'findImportStatusByRepo';\n export const FIND_TASK_IMPORT_STATUS_BY_REPO = 'findTaskImportStatusByRepo';\n export const FIND_ORCHESTRATOR_IMPORT_STATUS_BY_REPO =\n 'findOrchestratorImportStatusByRepo';\n\n export const DELETE_IMPORT_BY_REPO = 'deleteImportByRepo';\n export const DELETE_TASK_IMPORT_BY_REPO = 'deleteTaskImportByRepo';\n export const DELETE_ORCHESTRATOR_IMPORT_BY_REPO =\n 'deleteOrchestratorImportByRepo';\n}\n\nconst SCM_TOKENS_MAX_BYTES = 4096;\n\nconst isValidTokenMap = (v: unknown): v is Record<string, string> =>\n typeof v === 'object' &&\n v !== null &&\n Object.values(v).every(val => typeof val === 'string' && val.length > 0);\n\nfunction parseScmTokensHeader(\n rawTokenHeader: string | undefined,\n logger: LoggerService,\n): Record<string, string> | undefined {\n let token: Record<string, string> | undefined;\n if (!rawTokenHeader) return undefined;\n if (rawTokenHeader.length > SCM_TOKENS_MAX_BYTES) {\n logger.warn('x-scm-tokens header exceeds maximum allowed size; ignoring');\n return undefined;\n }\n try {\n token = JSON.parse(rawTokenHeader) as Record<string, string>;\n if (typeof token !== 'object' || token === null || Array.isArray(token)) {\n throw new Error('x-scm-tokens must be a JSON object');\n }\n } catch (e) {\n throw new InputError(\n `Invalid x-scm-tokens header: ${(e as Error).message}`,\n );\n }\n\n if (!isValidTokenMap(token)) {\n throw new InputError(\n 'Invalid x-scm-tokens header: all values must be non-empty strings',\n );\n }\n return token;\n}\n\n/**\n * Router\n * @public\n */\nexport async function createRouter(\n options: RouterOptions,\n): Promise<express.Router> {\n const {\n logger,\n httpAuth,\n auth,\n permissions,\n config,\n cache,\n discovery,\n catalog,\n auditor,\n database,\n } = options;\n\n const knex = await migrate(database);\n const repositoryDao = new RepositoryDao(knex, logger, 'repositories');\n const taskDao = new ScaffolderTaskDao(knex);\n const taskLocationsDao = new TaskLocationsDao(knex);\n const orchestratorRepositoryDao = new RepositoryDao(\n knex,\n logger,\n 'orchestrator_repositories',\n );\n const orchestratorWorkflowDao = new OrchestratorWorkflowDao(knex);\n // GitHub and GitLab both implement the GitApiService interface; the router\n // selects the appropriate service per request based on approvalTool.\n const githubApiService = new GithubApiService(logger, config, cache);\n const gitlabApiService = new GitlabApiService(logger, config, cache);\n const catalogHttpClient = new CatalogHttpClient({\n logger,\n config,\n auth,\n catalog,\n });\n const catalogInfoGenerator = new CatalogInfoGenerator(\n logger,\n catalogHttpClient,\n );\n\n // create openapi requests handler\n const api = new OpenAPIBackend({\n ajvOpts: {\n verbose: true,\n formats: fullFormats, // open issue: https://github.com/openapistack/openapi-backend/issues/280\n },\n validate: true,\n definition: openApiDocument,\n handlers: {\n validationFail: async (c, _req: Request, res: Response) =>\n res.status(400).json({ err: c.validation.errors }),\n notFound: async (_c, req: Request, res: Response) =>\n res.status(404).json({ err: `'${req.method} ${req.path}' not found` }),\n notImplemented: async (_c, req: Request, res: Response) =>\n res\n .status(500)\n .json({ err: `'${req.method} ${req.path}' not implemented` }),\n },\n });\n\n const templateRef = config.getOptionalString('bulkImport.importTemplate');\n let finalTemplateRef: string | undefined;\n if (templateRef) {\n finalTemplateRef = getImportTemplateRef(templateRef);\n }\n\n const orchestratorWorkflowId = config.getOptionalString(\n 'bulkImport.orchestratorWorkflow',\n );\n\n await api.init();\n\n api.register(\n Operations.PING,\n async (_c: Context, _req: Request, res: Response) => {\n const result = await ping(logger);\n return res.status(result.statusCode).json(result.responseBody);\n },\n );\n\n api.register(\n Operations.FIND_ALL_SCM_HOSTS,\n async (_c: Context, _req: Request, res: Response) => {\n const result = await findAllSCMHosts(config);\n return res.status(result.statusCode).json(result.responseBody);\n },\n );\n\n api.register(\n Operations.FIND_ALL_ORGANIZATIONS,\n async (c: Context, _req: Request, res: Response) => {\n const q: Paths.FindAllOrganizations.QueryParameters = {\n ...c.request.query,\n };\n // we need to convert strings to real types due to open PR https://github.com/openapistack/openapi-backend/pull/571\n q.pagePerIntegration = stringToNumber(q.pagePerIntegration);\n q.sizePerIntegration = stringToNumber(q.sizePerIntegration);\n const response = await findAllOrganizations(\n logger,\n q.approvalTool === 'GITLAB' ? gitlabApiService : githubApiService,\n q.search,\n q.pagePerIntegration,\n q.sizePerIntegration,\n );\n return res.status(response.statusCode).json({\n errors: response.responseBody?.errors,\n organizations: response.responseBody?.organizations,\n totalCount: response.responseBody?.totalCount,\n pagePerIntegration: response.responseBody?.pagePerIntegration,\n sizePerIntegration: response.responseBody?.sizePerIntegration,\n approvalTool: q.approvalTool,\n } as Components.Schemas.OrganizationList);\n },\n );\n\n api.register(\n Operations.FIND_ALL_REPOSITORIES,\n async (c: Context, _req: Request, res: Response) => {\n const q: Paths.FindAllRepositories.QueryParameters = {\n ...c.request.query,\n };\n // we need to convert strings to real types due to open PR https://github.com/openapistack/openapi-backend/pull/571\n q.pagePerIntegration = stringToNumber(q.pagePerIntegration);\n q.sizePerIntegration = stringToNumber(q.sizePerIntegration);\n q.checkImportStatus = stringToBoolean(q.checkImportStatus);\n\n const userTokens = res.locals.scmTokens as\n | Record<string, string>\n | undefined;\n\n if (!userTokens || Object.keys(userTokens).length === 0) {\n return res.status(401).json({\n error:\n 'User SCM credentials are required to list repositories. Ensure the SCM OAuth integration is configured.',\n });\n }\n\n const response = await findAllRepositories(\n {\n logger,\n config,\n gitApiService:\n q.approvalTool === 'GITLAB' ? gitlabApiService : githubApiService,\n catalogHttpClient,\n },\n {\n search: q.search,\n checkStatus: q.checkImportStatus,\n pageNumber: q.pagePerIntegration,\n pageSize: q.sizePerIntegration,\n userTokens,\n },\n );\n const repos = response.responseBody?.repositories;\n return res.status(response.statusCode).json({\n errors: response.responseBody?.errors,\n repositories: repos,\n totalCount: response.responseBody?.totalCount,\n pagePerIntegration: q.pagePerIntegration,\n sizePerIntegration: q.sizePerIntegration,\n approvalTool: q.approvalTool,\n } as Components.Schemas.RepositoryList);\n },\n );\n\n api.register(\n Operations.FIND_REPOSITORIES_BY_ORGANIZATION,\n async (c: Context, _req: Request, res: Response) => {\n const q: Paths.FindRepositoriesByOrganization.QueryParameters = {\n ...c.request.query,\n };\n // we need to convert strings to real types due to open PR https://github.com/openapistack/openapi-backend/pull/571\n q.pagePerIntegration = stringToNumber(q.pagePerIntegration);\n q.sizePerIntegration = stringToNumber(q.sizePerIntegration);\n q.checkImportStatus = stringToBoolean(q.checkImportStatus);\n\n const userTokens = res.locals.scmTokens as\n | Record<string, string>\n | undefined;\n\n if (!userTokens || Object.keys(userTokens).length === 0) {\n return res.status(401).json({\n error:\n 'User SCM credentials are required to list repositories. Ensure the SCM OAuth integration is configured.',\n });\n }\n\n const response = await findRepositoriesByOrganization(\n {\n logger,\n config,\n gitApiService:\n q.approvalTool === 'GITLAB' ? gitlabApiService : githubApiService,\n catalogHttpClient,\n },\n c.request.params.organizationName?.toString(),\n q.search,\n q.checkImportStatus,\n q.pagePerIntegration,\n q.sizePerIntegration,\n userTokens,\n );\n const repos = response.responseBody?.repositories;\n return res.status(response.statusCode).json({\n errors: response.responseBody?.errors,\n repositories: repos,\n totalCount: response.responseBody?.totalCount,\n pagePerIntegration: q.pagePerIntegration,\n sizePerIntegration: q.sizePerIntegration,\n approvalTool: q.approvalTool,\n } as Components.Schemas.RepositoryList);\n },\n );\n\n api.register(\n Operations.FIND_ALL_IMPORTS,\n async (c: Context, _req: Request, res: Response) => {\n const {\n pageNumber,\n pageSize,\n apiVersion,\n search,\n sortColumn,\n sortOrder,\n } = getFindImportsParams(c);\n const response = await findAllImports(\n {\n logger,\n config,\n githubApiService,\n gitlabApiService,\n catalogHttpClient,\n },\n {\n apiVersion,\n },\n {\n search,\n pageNumber,\n pageSize,\n sortColumn,\n sortOrder,\n },\n );\n return res.status(response.statusCode).json(response.responseBody);\n },\n );\n api.register(\n Operations.FIND_ALL_TASK_IMPORTS,\n async (c: Context, _req: Request, res: Response) => {\n const { pageNumber, pageSize, search, sortColumn, sortOrder } =\n getFindImportsParams(c);\n const imports: SourceImport[] = [];\n const repositories = await repositoryDao.findRepositories(\n pageNumber,\n pageSize,\n search,\n );\n\n for (const repo of repositories.data) {\n const response = await findTaskImportStatusByRepo(\n {\n logger,\n config,\n githubApiService,\n gitlabApiService,\n catalogHttpClient,\n repositoryDao,\n taskDao,\n taskLocationsDao,\n discovery,\n auth,\n },\n repo.url,\n true,\n );\n if (response.responseBody) {\n imports.push(response.responseBody);\n }\n }\n\n sortImports(imports, sortColumn, sortOrder);\n\n const responseBody: Components.Schemas.ImportJobListV2 = {\n imports,\n totalCount: repositories.total,\n page: pageNumber || 1,\n size: pageSize || 5,\n };\n\n return res.status(200).json(responseBody);\n },\n );\n\n api.register(\n Operations.FIND_ALL_ORCHESTRATOR_WORKFLOW_IMPORTS,\n async (c: Context, req: Request, res: Response) => {\n const { pageNumber, pageSize, search, sortColumn, sortOrder } =\n getFindImportsParams(c);\n const imports: SourceImport[] = [];\n const repositories = await orchestratorRepositoryDao.findRepositories(\n pageNumber,\n pageSize,\n search,\n );\n\n const token = getBearerTokenFromReq(req);\n\n for (const repo of repositories.data) {\n const response = await findOrchestratorImportStatusByRepo(\n {\n logger,\n orchestratorRepositoryDao,\n orchestratorWorkflowDao,\n discovery,\n },\n repo.url,\n token,\n true,\n );\n if (response.responseBody) {\n imports.push(response.responseBody);\n }\n }\n\n sortImports(imports, sortColumn, sortOrder);\n\n const responseBody: Components.Schemas.ImportJobListV2 = {\n imports,\n totalCount: repositories.total,\n page: pageNumber || 1,\n size: pageSize || 5,\n };\n\n return res.status(200).json(responseBody);\n },\n );\n\n api.register(\n Operations.CREATE_IMPORT_JOBS,\n async (\n c: Context<Paths.CreateImportJobs.RequestBody>,\n _req: Request,\n res: Response,\n ) => {\n const q: Paths.CreateImportJobs.QueryParameters = {\n ...c.request.query,\n };\n q.dryRun = stringToBoolean(q.dryRun);\n const response = await createImportJobs(\n {\n logger,\n config,\n auth,\n gitlabApiService,\n githubApiService,\n catalogInfoGenerator,\n catalogHttpClient,\n },\n {\n importRequests: c.request.requestBody,\n dryRun: q.dryRun,\n },\n );\n return res.status(response.statusCode).json(response.responseBody);\n },\n );\n\n api.register(\n Operations.CREATE_TASK_IMPORT_JOBS,\n async (\n c: Context<Paths.CreateImportJobs.RequestBody>,\n _req: Request,\n res: Response,\n ) => {\n if (!finalTemplateRef) {\n throw new Error(\n `Missing required config value: 'bulkImport.importTemplate'`,\n );\n }\n const response = await createTaskImportJobs(\n finalTemplateRef,\n discovery,\n logger,\n auth,\n config,\n repositoryDao,\n taskDao,\n taskLocationsDao,\n c.request.requestBody,\n githubApiService,\n );\n\n return res.status(response.statusCode).json(response.responseBody);\n },\n );\n\n api.register(\n Operations.CREATE_ORCHESTRATOR_WORKFLOW_JOBS,\n async (\n c: Context<Paths.CreateImportJobs.RequestBody>,\n req: Request,\n res: Response,\n ) => {\n if (!orchestratorWorkflowId) {\n throw new Error(\n `Missing required config value: 'bulkImport.orchestratorWorkflow'`,\n );\n }\n\n const token = getBearerTokenFromReq(req);\n\n const response = await createWorkflowImportJobs({\n orchestratorWorkflowId,\n discovery,\n token,\n requestBody: c.request.requestBody,\n orchestratorWorkflowDao,\n orchestratorRepositoryDao,\n githubApiService,\n gitlabApiService,\n });\n\n res.status(response.statusCode).json(response.responseBody);\n },\n );\n\n api.register(\n Operations.FIND_TASK_IMPORT_STATUS_BY_REPO,\n async (c: Context, _req: Request, res: Response) => {\n const q: Paths.FindImportStatusByRepo.QueryParameters = {\n ...c.request.query,\n };\n if (!q.repo?.trim()) {\n throw new Error('missing or blank parameter');\n }\n const response = await findTaskImportStatusByRepo(\n {\n logger,\n config,\n githubApiService,\n gitlabApiService,\n catalogHttpClient,\n repositoryDao,\n taskDao,\n taskLocationsDao,\n discovery,\n auth,\n },\n q.repo,\n );\n return res.status(response.statusCode).json(response.responseBody);\n },\n );\n\n api.register(\n Operations.FIND_IMPORT_STATUS_BY_REPO,\n async (c: Context, _req: Request, res: Response) => {\n const q: Paths.FindImportStatusByRepo.QueryParameters = {\n ...c.request.query,\n };\n if (!q.repo?.trim()) {\n throw new Error('missing or blank parameter');\n }\n const response = await findImportStatusByRepo(\n {\n logger,\n config,\n gitApiService:\n q.approvalTool === 'GITLAB' ? gitlabApiService : githubApiService,\n catalogHttpClient,\n approvalTool: q.approvalTool,\n },\n q.repo,\n q.defaultBranch,\n true,\n );\n return res.status(response.statusCode).json(response.responseBody);\n },\n );\n\n api.register(\n Operations.FIND_ORCHESTRATOR_IMPORT_STATUS_BY_REPO,\n async (c: Context, req: Request, res: Response) => {\n const q: Paths.FindImportStatusByRepo.QueryParameters = {\n ...c.request.query,\n };\n if (!q.repo?.trim()) {\n throw new Error('missing or blank parameter');\n }\n const token = getBearerTokenFromReq(req);\n const response = await findOrchestratorImportStatusByRepo(\n {\n logger,\n orchestratorRepositoryDao,\n orchestratorWorkflowDao,\n discovery,\n },\n q.repo,\n token,\n );\n return res.status(response.statusCode).json(response.responseBody);\n },\n );\n\n api.register(\n Operations.DELETE_TASK_IMPORT_BY_REPO,\n async (c: Context, _req: Request, res: Response) => {\n const q: Paths.DeleteImportByRepo.QueryParameters = {\n ...c.request.query,\n };\n if (!q.repo?.trim()) {\n throw new Error('missing or blank \"repo\" parameter');\n }\n const response = await deleteRepositoryRecord(\n {\n logger,\n dao: repositoryDao,\n },\n q.repo,\n );\n return res.status(response.statusCode).json(response.responseBody);\n },\n );\n\n api.register(\n Operations.DELETE_IMPORT_BY_REPO,\n async (c: Context, _req: Request, res: Response) => {\n const q: Paths.DeleteImportByRepo.QueryParameters = {\n ...c.request.query,\n };\n if (!q.repo?.trim()) {\n throw new Error('missing or blank \"repo\" parameter');\n }\n const response = await deleteImportByRepo(\n {\n logger,\n config,\n gitApiService:\n parseGitURLForApprovalTool(q.repo) === 'GITLAB'\n ? gitlabApiService\n : githubApiService,\n catalogHttpClient,\n },\n q.repo,\n q.defaultBranch,\n );\n return res.status(response.statusCode).json(response.responseBody);\n },\n );\n\n api.register(\n Operations.DELETE_ORCHESTRATOR_IMPORT_BY_REPO,\n async (c: Context, _req: Request, res: Response) => {\n const q: Paths.DeleteImportByRepo.QueryParameters = {\n ...c.request.query,\n };\n if (!q.repo?.trim()) {\n throw new Error('missing or blank \"repo\" parameter');\n }\n const response = await deleteRepositoryRecord(\n {\n logger,\n dao: orchestratorRepositoryDao,\n },\n q.repo,\n );\n return res.status(response.statusCode).json(response.responseBody);\n },\n );\n\n const router = Router();\n router.use(express.json());\n\n // Strip x-scm-tokens from req.headers before the permission check and audit\n // middleware run so that OAuth tokens are never captured in audit logs.\n // The parsed map is stored in res.locals.scmTokens for handler use.\n router.use((req, res, next) => {\n const raw = req.headers['x-scm-tokens'];\n const rawStr = Array.isArray(raw) ? raw[0] : raw;\n delete req.headers['x-scm-tokens'];\n if (rawStr) {\n try {\n res.locals.scmTokens = parseScmTokensHeader(rawStr, logger);\n } catch (e) {\n next(e);\n return;\n }\n }\n next();\n });\n\n router.use(async (req, _res, next) => {\n if (req.path !== '/ping') {\n try {\n await permissionCheck(\n auditor,\n api.matchOperation(req as OpenAPIRequest)?.operationId,\n permissions,\n httpAuth,\n req,\n );\n } catch (e) {\n next(e);\n return;\n }\n }\n next();\n });\n\n router.use(async (req, res, next) => {\n const reqCast = req as OpenAPIRequest;\n const operationId = api.matchOperation(reqCast)?.operationId;\n\n const auditorEvent = await createAuditorEventByOperationId(\n operationId,\n req,\n auditor,\n );\n try {\n const response = (await api.handleRequest(reqCast, req, res)) as Response;\n auditorEvent?.success({ meta: { responseStatus: response.statusCode } });\n next();\n } catch (err: any) {\n auditorEvent?.fail({ error: err, meta: { responseStatus: 500 } });\n next(err);\n }\n });\n\n const middleware = MiddlewareFactory.create({ logger, config });\n router.use(middleware.error());\n\n return router;\n}\n\nasync function createAuditorEventByOperationId(\n operationId: string | undefined,\n req: Request,\n auditor: AuditorService,\n): Promise<AuditorServiceEvent | undefined> {\n let auditorEvent;\n switch (operationId) {\n case Operations.PING:\n auditorEvent = await auditCreateEvent(auditor, 'ping', req);\n break;\n case Operations.FIND_ALL_SCM_HOSTS:\n auditorEvent = await auditCreateEvent(auditor, 'scm-hosts-read', req);\n break;\n\n case Operations.FIND_ALL_ORGANIZATIONS:\n auditorEvent = await auditCreateEvent(auditor, 'org-read', req, {\n queryType: req.query.search ? 'by-query' : 'all',\n search: req.query?.search,\n });\n break;\n case Operations.FIND_ALL_REPOSITORIES:\n auditorEvent = await auditCreateEvent(auditor, 'repo-read', req, {\n queryType: req.query.search ? 'by-query' : 'all',\n search: req.query.search,\n });\n break;\n case Operations.FIND_REPOSITORIES_BY_ORGANIZATION: {\n const organizationName = req.params.organizationName?.toString();\n auditorEvent = await auditCreateEvent(auditor, 'repo-read', req, {\n queryType: 'by-org',\n organizationName,\n });\n break;\n }\n case Operations.FIND_ALL_IMPORTS:\n case Operations.FIND_ALL_TASK_IMPORTS:\n case Operations.FIND_ALL_ORCHESTRATOR_WORKFLOW_IMPORTS:\n auditorEvent = await auditCreateEvent(auditor, 'import-read', req, {\n queryType: req.query.search ? 'by-query' : 'all',\n search: req.query.search,\n });\n break;\n case Operations.CREATE_IMPORT_JOBS:\n case Operations.CREATE_TASK_IMPORT_JOBS:\n case Operations.CREATE_ORCHESTRATOR_WORKFLOW_JOBS:\n auditorEvent = await auditCreateEvent(auditor, 'import-write', req, {\n actionType: 'create',\n });\n break;\n case Operations.FIND_IMPORT_STATUS_BY_REPO:\n case Operations.FIND_TASK_IMPORT_STATUS_BY_REPO:\n case Operations.FIND_ORCHESTRATOR_IMPORT_STATUS_BY_REPO:\n auditorEvent = await auditCreateEvent(\n auditor,\n 'import-status-read',\n req,\n { queryType: 'by-query', repo: req.query.repo },\n );\n break;\n case Operations.DELETE_IMPORT_BY_REPO:\n case Operations.DELETE_TASK_IMPORT_BY_REPO:\n case Operations.DELETE_ORCHESTRATOR_IMPORT_BY_REPO:\n auditorEvent = await auditCreateEvent(auditor, 'import-write', req, {\n actionType: 'delete',\n repository: req.query.repo,\n });\n break;\n case undefined:\n auditorEvent = await auditCreateEvent(auditor, operationId, req);\n break;\n default:\n // do nothing\n break;\n }\n return auditorEvent;\n}\n\nfunction stringToNumber(s: number | undefined): number | undefined {\n return s ? Number.parseInt(s.toString(), 10) : undefined;\n}\n\nfunction stringToBoolean(s: boolean | undefined): boolean | undefined {\n if (!s) {\n return undefined;\n }\n return s.toString() === 'true';\n}\nfunction getFindImportsParams(c: Context<any, any, any, any, any, Document>): {\n pageNumber?: number;\n pageSize?: number;\n apiVersion?: Paths.FindAllImports.Parameters.ApiVersion;\n search?: string;\n sortColumn?: Components.Parameters.SortColumnQueryParam;\n sortOrder?: Components.Parameters.SortOrderQueryParam;\n} {\n const h: Paths.FindAllImports.HeaderParameters = {\n ...c.request.headers,\n };\n const apiVersion = h['api-version'];\n const q: Paths.FindAllImports.QueryParameters = {\n ...c.request.query,\n };\n // we need to convert strings to real types due to open PR https://github.com/openapistack/openapi-backend/pull/571\n let pageNumber: number | undefined;\n let pageSize: number | undefined;\n if (apiVersion === undefined || apiVersion === 'v1') {\n // pagePerIntegration and sizePerIntegration deprecated in v1. 'page' and 'size' take precedence.\n pageNumber = stringToNumber(q.page || q.pagePerIntegration);\n pageSize = stringToNumber(q.size || q.sizePerIntegration);\n } else {\n // pagePerIntegration and sizePerIntegration removed in v2+ and replaced by 'page' and 'size'.\n pageNumber = stringToNumber(q.page);\n pageSize = stringToNumber(q.size);\n }\n return {\n pageNumber,\n pageSize,\n apiVersion: apiVersion,\n search: q.search,\n sortColumn: q.sortColumn,\n sortOrder: q.sortOrder,\n };\n}\n\nfunction getBearerTokenFromReq(req: express.Request): string {\n const header = req.header('authorization') ?? req.headers.authorization;\n if (header?.startsWith(`Bearer `)) {\n return header.replace('Bearer ', '');\n }\n throw new InputError(`Request provided without token`);\n}\n"],"names":["Operations","InputError","auth","migrate","repositoryDao","RepositoryDao","ScaffolderTaskDao","TaskLocationsDao","OrchestratorWorkflowDao","githubApiService","GithubApiService","gitlabApiService","GitlabApiService","catalogHttpClient","CatalogHttpClient","catalogInfoGenerator","CatalogInfoGenerator","OpenAPIBackend","fullFormats","openApiDocument","getImportTemplateRef","ping","findAllSCMHosts","findAllOrganizations","findAllRepositories","findRepositoriesByOrganization","findAllImports","findTaskImportStatusByRepo","sortImports","findOrchestratorImportStatusByRepo","createImportJobs","createTaskImportJobs","createWorkflowImportJobs","findImportStatusByRepo","deleteRepositoryRecord","deleteImportByRepo","parseGitURLForApprovalTool","Router","express","permissionCheck","MiddlewareFactory","auditCreateEvent"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@red-hat-developer-hub/backstage-plugin-bulk-import-backend",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "8.0.0",
|
|
4
4
|
"main": "./dist/index.cjs.js",
|
|
5
5
|
"types": "./dist/index.d.ts",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -50,44 +50,41 @@
|
|
|
50
50
|
"openapi": "./scripts/openapi.sh"
|
|
51
51
|
},
|
|
52
52
|
"dependencies": {
|
|
53
|
-
"@backstage/backend-defaults": "
|
|
54
|
-
"@backstage/backend-plugin-api": "^1.
|
|
55
|
-
"@backstage/catalog-model": "^1.
|
|
56
|
-
"@backstage/config": "^1.3.
|
|
57
|
-
"@backstage/errors": "^1.
|
|
58
|
-
"@backstage/integration": "^2.0.
|
|
59
|
-
"@backstage/plugin-catalog-node": "^2.
|
|
60
|
-
"@backstage/plugin-permission-common": "^0.9.
|
|
61
|
-
"@backstage/plugin-permission-node": "^0.10.11",
|
|
53
|
+
"@backstage/backend-defaults": "0.17.3",
|
|
54
|
+
"@backstage/backend-plugin-api": "^1.9.2",
|
|
55
|
+
"@backstage/catalog-model": "^1.9.0",
|
|
56
|
+
"@backstage/config": "^1.3.8",
|
|
57
|
+
"@backstage/errors": "^1.3.1",
|
|
58
|
+
"@backstage/integration": "^2.0.3",
|
|
59
|
+
"@backstage/plugin-catalog-node": "^2.2.2",
|
|
60
|
+
"@backstage/plugin-permission-common": "^0.9.9",
|
|
62
61
|
"@gitbeaker/rest": "^43.4.0",
|
|
63
62
|
"@octokit/auth-app": "^7.2.2",
|
|
64
63
|
"@octokit/rest": "^20.0.2",
|
|
65
|
-
"@red-hat-developer-hub/backstage-plugin-bulk-import-common": "^
|
|
66
|
-
"@red-hat-developer-hub/backstage-plugin-orchestrator-common": "^3.
|
|
64
|
+
"@red-hat-developer-hub/backstage-plugin-bulk-import-common": "^8.0.0",
|
|
65
|
+
"@red-hat-developer-hub/backstage-plugin-orchestrator-common": "^3.7.3",
|
|
67
66
|
"ajv-formats": "^3.0.1",
|
|
68
67
|
"eventsource-client": "^1.2.0",
|
|
69
68
|
"express": "^4.17.1",
|
|
70
69
|
"git-url-parse": "^14.0.0",
|
|
71
|
-
"js-yaml": "^4.
|
|
70
|
+
"js-yaml": "^4.3.0",
|
|
72
71
|
"just-kebab-case": "4.2.0",
|
|
73
72
|
"knex": "^3.0.0",
|
|
74
73
|
"luxon": "^3.4.4",
|
|
75
|
-
"node-fetch": "^2.6.7",
|
|
76
74
|
"openapi-backend": "^5.10.6"
|
|
77
75
|
},
|
|
78
76
|
"devDependencies": {
|
|
79
|
-
"@backstage/backend-test-utils": "^1.11.
|
|
80
|
-
"@backstage/catalog-client": "^1.
|
|
81
|
-
"@backstage/cli": "^0.36.
|
|
82
|
-
"@backstage/config": "^1.3.
|
|
83
|
-
"@backstage/plugin-catalog-backend": "^3.
|
|
77
|
+
"@backstage/backend-test-utils": "^1.11.4",
|
|
78
|
+
"@backstage/catalog-client": "^1.16.0",
|
|
79
|
+
"@backstage/cli": "^0.36.3",
|
|
80
|
+
"@backstage/config": "^1.3.8",
|
|
81
|
+
"@backstage/plugin-catalog-backend": "^3.8.0",
|
|
84
82
|
"@backstage/types": "^1.2.2",
|
|
85
83
|
"@openapitools/openapi-generator-cli": "2.39.0",
|
|
86
84
|
"@spotify/prettier-config": "^15.0.0",
|
|
87
85
|
"@types/express": "4.17.25",
|
|
88
86
|
"@types/git-url-parse": "^9.0.0",
|
|
89
87
|
"@types/knex": "^0.16.1",
|
|
90
|
-
"@types/node-fetch": "^2.5.12",
|
|
91
88
|
"@types/supertest": "2.0.16",
|
|
92
89
|
"js-yaml-cli": "0.6.0",
|
|
93
90
|
"msw": "1.3.5",
|
|
@@ -98,12 +95,12 @@
|
|
|
98
95
|
"files": [
|
|
99
96
|
"dist",
|
|
100
97
|
"migrations",
|
|
101
|
-
"config.
|
|
98
|
+
"config.schema.json",
|
|
102
99
|
"dist-dynamic/*.*",
|
|
103
100
|
"dist-dynamic/dist/**",
|
|
104
101
|
"app-config.yaml"
|
|
105
102
|
],
|
|
106
|
-
"configSchema": "config.
|
|
103
|
+
"configSchema": "config.schema.json",
|
|
107
104
|
"repository": {
|
|
108
105
|
"type": "git",
|
|
109
106
|
"url": "https://github.com/redhat-developer/rhdh-plugins",
|
package/config.d.ts
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright Red Hat, Inc.
|
|
3
|
-
*
|
|
4
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
-
* you may not use this file except in compliance with the License.
|
|
6
|
-
* You may obtain a copy of the License at
|
|
7
|
-
*
|
|
8
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
-
*
|
|
10
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
-
* See the License for the specific language governing permissions and
|
|
14
|
-
* limitations under the License.
|
|
15
|
-
*/
|
|
16
|
-
|
|
17
|
-
export interface Config {
|
|
18
|
-
bulkImport?: {
|
|
19
|
-
/**
|
|
20
|
-
* The name of the scaffolder template or entity reference to execute for importing a repository.
|
|
21
|
-
* @visibility backend
|
|
22
|
-
*/
|
|
23
|
-
importTemplate?: string;
|
|
24
|
-
/**
|
|
25
|
-
* The orchestrator workflow id to execute for importing a repository.
|
|
26
|
-
* @visibility backend
|
|
27
|
-
*/
|
|
28
|
-
orchestratorWorkflow?: string;
|
|
29
|
-
};
|
|
30
|
-
}
|