@red-hat-developer-hub/backstage-plugin-bulk-import-backend 6.10.1 → 6.11.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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"execute-orchestrator-workflow.cjs.js","sources":["../../../../src/service/handlers/import/execute-orchestrator-workflow.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 */\nimport { DiscoveryApi } from '@backstage/plugin-permission-common';\n\nimport {\n AuthToken,\n Configuration,\n DefaultApi,\n ExecuteWorkflowRequestDTO,\n} from '@red-hat-developer-hub/backstage-plugin-orchestrator-common';\n\nimport {\n OrchestratorWorkflowDao,\n RepositoryDao,\n} from '../../../database/repositoryDao';\nimport { Components, ImportRequest } from '../../../generated/openapi';\nimport { GithubApiService } from '../../../github';\nimport { GitlabApiService } from '../../../gitlab';\nimport { HandlerResponse } from '../handlers';\nimport { sortImports } from './bulkImports';\n\nexport type CreateWorkflowImportJobsArgs = {\n orchestratorWorkflowId: string;\n discovery: DiscoveryApi;\n token?: string;\n requestBody: ImportRequest[];\n orchestratorWorkflowDao: OrchestratorWorkflowDao;\n orchestratorRepositoryDao: RepositoryDao<'orchestrator_repositories'>;\n githubApiService: GithubApiService;\n gitlabApiService: GitlabApiService;\n};\n\nexport async function createWorkflowImportJobs(\n args: CreateWorkflowImportJobsArgs,\n): Promise<HandlerResponse<Components.Schemas.Import[]>> {\n const {\n orchestratorWorkflowId,\n discovery,\n token,\n requestBody,\n orchestratorWorkflowDao,\n orchestratorRepositoryDao,\n githubApiService,\n gitlabApiService,\n } = args;\n\n if (requestBody.length === 0) {\n return {\n statusCode: 400,\n responseBody: [],\n };\n }\n\n const result: Components.Schemas.Import[] = [];\n const baseUrl = await discovery.getBaseUrl('orchestrator');\n const apiConfig = new Configuration();\n\n // Initialize the client\n const orchestratorApi = new DefaultApi(apiConfig, baseUrl);\n\n for (const repo of requestBody) {\n if (!repo.repository.url) {\n continue;\n }\n\n let workflowStatus: Components.Schemas.WorkflowImportStatus | undefined;\n try {\n const approvalTool = repo.approvalTool ?? 'GIT';\n\n const authTokens: AuthToken[] = [];\n if (approvalTool === 'GIT') {\n const creds = await githubApiService.getCredentials(\n repo.repository.url,\n );\n authTokens.push({ token: creds?.token, provider: 'github' });\n }\n if (approvalTool === 'GITLAB') {\n const creds = await gitlabApiService.getCredentials(\n repo.repository.url,\n );\n authTokens.push({ token: creds?.token, provider: 'gitlab' });\n }\n\n const requestDTO: ExecuteWorkflowRequestDTO = {\n inputData: {\n owner: repo.repository.organization,\n repo: repo.repository.name,\n baseBranch: repo.repository.defaultBranch,\n targetBranch: `bulk-import-orchestrator`,\n approvalTool: approvalTool,\n },\n authTokens,\n };\n\n // Execute a workflow\n const wfResult = await orchestratorApi.executeWorkflow(\n orchestratorWorkflowId,\n requestDTO,\n {\n headers: {\n Authorization: `Bearer ${token}`,\n 'Content-Type': 'application/json',\n },\n },\n );\n\n const repositoryId = await orchestratorRepositoryDao.insertRepository(\n repo.repository.url,\n wfResult.data.id,\n approvalTool,\n );\n await orchestratorWorkflowDao.insertWorkflow(\n wfResult.data.id,\n repositoryId,\n );\n\n const response = await orchestratorApi.getInstanceById(wfResult.data.id, {\n headers: {\n Authorization: `Bearer ${token}`,\n 'Content-Type': 'application/json',\n },\n });\n workflowStatus =\n `WORKFLOW_${(response.data.state as string)?.toLocaleUpperCase()}` as Components.Schemas.WorkflowImportStatus;\n\n result.push({\n repository: repo.repository,\n workflow: { workflowId: wfResult.data.id },\n status: workflowStatus,\n });\n } catch (error: any) {\n result.push({\n repository: repo.repository,\n status: workflowStatus ?? 'WORKFLOW_ABORTED',\n errors: [(error as Error).message],\n });\n }\n }\n\n sortImports(result);\n\n return {\n statusCode: 202,\n responseBody: result,\n };\n}\n"],"names":["Configuration","DefaultApi","sortImports"],"mappings":";;;;;AA6CA,eAAsB,yBACpB,IACuD,EAAA;AACvD,EAAM,MAAA;AAAA,IACJ,sBAAA;AAAA,IACA,SAAA;AAAA,IACA,KAAA;AAAA,IACA,WAAA;AAAA,IACA,uBAAA;AAAA,IACA,yBAAA;AAAA,IACA,gBAAA;AAAA,IACA;AAAA,GACE,GAAA,IAAA;AAEJ,EAAI,IAAA,WAAA,CAAY,WAAW,CAAG,EAAA;AAC5B,IAAO,OAAA;AAAA,MACL,UAAY,EAAA,GAAA;AAAA,MACZ,cAAc;AAAC,KACjB;AAAA;AAGF,EAAA,MAAM,SAAsC,EAAC;AAC7C,EAAA,MAAM,OAAU,GAAA,MAAM,SAAU,CAAA,UAAA,CAAW,cAAc,CAAA;AACzD,EAAM,MAAA,SAAA,GAAY,IAAIA,+CAAc,EAAA;AAGpC,EAAA,MAAM,eAAkB,GAAA,IAAIC,4CAAW,CAAA,SAAA,EAAW,OAAO,CAAA;AAEzD,EAAA,KAAA,MAAW,QAAQ,WAAa,EAAA;AAC9B,IAAI,IAAA,CAAC,IAAK,CAAA,UAAA,CAAW,GAAK,EAAA;AACxB,MAAA;AAAA;AAGF,IAAI,IAAA,cAAA;AACJ,IAAI,IAAA;AACF,MAAM,MAAA,YAAA,GAAe,KAAK,YAAgB,IAAA,KAAA;AAE1C,MAAA,MAAM,aAA0B,EAAC;AACjC,MAAA,IAAI,iBAAiB,KAAO,EAAA;AAC1B,QAAM,MAAA,KAAA,GAAQ,MAAM,gBAAiB,CAAA,cAAA;AAAA,UACnC,KAAK,UAAW,CAAA;AAAA,SAClB;AACA,QAAA,UAAA,CAAW,KAAK,EAAE,KAAA,EAAO,OAAO,KAAO,EAAA,QAAA,EAAU,UAAU,CAAA;AAAA;AAE7D,MAAA,IAAI,iBAAiB,QAAU,EAAA;AAC7B,QAAM,MAAA,KAAA,GAAQ,MAAM,gBAAiB,CAAA,cAAA;AAAA,UACnC,KAAK,UAAW,CAAA;AAAA,SAClB;AACA,QAAA,UAAA,CAAW,KAAK,EAAE,KAAA,EAAO,OAAO,KAAO,EAAA,QAAA,EAAU,UAAU,CAAA;AAAA;AAG7D,MAAA,MAAM,UAAwC,GAAA;AAAA,QAC5C,SAAW,EAAA;AAAA,UACT,KAAA,EAAO,KAAK,UAAW,CAAA,YAAA;AAAA,UACvB,IAAA,EAAM,KAAK,UAAW,CAAA,IAAA;AAAA,UACtB,UAAA,EAAY,KAAK,UAAW,CAAA,aAAA;AAAA,UAC5B,YAAc,EAAA,CAAA,wBAAA,CAAA;AAAA,UACd;AAAA,SACF;AAAA,QACA;AAAA,OACF;AAGA,MAAM,MAAA,QAAA,GAAW,MAAM,eAAgB,CAAA,eAAA;AAAA,QACrC,sBAAA;AAAA,QACA,UAAA;AAAA,QACA;AAAA,UACE,OAAS,EAAA;AAAA,YACP,aAAA,EAAe,UAAU,KAAK,CAAA,CAAA;AAAA,YAC9B,cAAgB,EAAA;AAAA;AAClB;AACF,OACF;AAEA,MAAM,MAAA,YAAA,GAAe,MAAM,yBAA0B,CAAA,gBAAA;AAAA,QACnD,KAAK,UAAW,CAAA,GAAA;AAAA,QAChB,SAAS,IAAK,CAAA,EAAA;AAAA,QACd;AAAA,OACF;AACA,MAAA,MAAM,uBAAwB,CAAA,cAAA;AAAA,QAC5B,SAAS,IAAK,CAAA,EAAA;AAAA,QACd;AAAA,OACF;AAEA,MAAA,MAAM,WAAW,MAAM,eAAA,CAAgB,eAAgB,CAAA,QAAA,CAAS,KAAK,EAAI,EAAA;AAAA,QACvE,OAAS,EAAA;AAAA,UACP,aAAA,EAAe,UAAU,KAAK,CAAA,CAAA;AAAA,UAC9B,cAAgB,EAAA;AAAA;AAClB,OACD,CAAA;AACD,MAAA,cAAA,GACE,CAAa,SAAA,EAAA,QAAA,CAAS,IAAK,CAAA,KAAA,EAAkB,mBAAmB,CAAA,CAAA;AAElE,MAAA,MAAA,CAAO,IAAK,CAAA;AAAA,QACV,YAAY,IAAK,CAAA,UAAA;AAAA,QACjB,QAAU,EAAA,EAAE,UAAY,EAAA,QAAA,CAAS,KAAK,EAAG,EAAA;AAAA,QACzC,MAAQ,EAAA;AAAA,OACT,CAAA;AAAA,aACM,KAAY,EAAA;AACnB,MAAA,MAAA,CAAO,IAAK,CAAA;AAAA,QACV,YAAY,IAAK,CAAA,UAAA;AAAA,QACjB,QAAQ,cAAkB,IAAA,kBAAA;AAAA,QAC1B,MAAA,EAAQ,CAAE,KAAA,CAAgB,OAAO;AAAA,OAClC,CAAA;AAAA;AACH;AAGF,EAAAC,uBAAA,CAAY,MAAM,CAAA;AAElB,EAAO,OAAA;AAAA,IACL,UAAY,EAAA,GAAA;AAAA,IACZ,YAAc,EAAA;AAAA,GAChB;AACF;;;;"}
@@ -3,6 +3,7 @@
3
3
  var eventsourceClient = require('eventsource-client');
4
4
  var gitUrlParse = require('git-url-parse');
5
5
  var catalogUtils = require('../../../catalog/catalogUtils.cjs.js');
6
+ var bulkImports = require('./bulkImports.cjs.js');
6
7
 
7
8
  function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
8
9
 
@@ -96,7 +97,7 @@ const handlePullRequestUpdate = async (importReq, logger, config, githubApiServi
96
97
  } catch (err) {
97
98
  logger.error(`Failed to update pull request ${prUrl}`, err);
98
99
  result.status = "PR_ERROR";
99
- result.errors = [err];
100
+ result.errors = [err.message];
100
101
  return result;
101
102
  }
102
103
  result.status = "WAIT_PR_APPROVAL";
@@ -216,12 +217,7 @@ const createTaskImportJobs = async (templateRef, discovery, logger, auth, config
216
217
  }
217
218
  }
218
219
  }
219
- if (result.some((r) => r.errors)) {
220
- return {
221
- statusCode: 202,
222
- responseBody: { errors: result.flatMap((r) => r.errors || []) }
223
- };
224
- }
220
+ bulkImports.sortImports(result);
225
221
  return {
226
222
  statusCode: 202,
227
223
  responseBody: result
@@ -1 +1 @@
1
- {"version":3,"file":"execute-template.cjs.js","sources":["../../../../src/service/handlers/import/execute-template.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 AuthService,\n DiscoveryService,\n LoggerService,\n} from '@backstage/backend-plugin-api';\nimport { Config } from '@backstage/config';\n\nimport { createEventSource } from 'eventsource-client';\nimport gitUrlParse from 'git-url-parse';\n\nimport { getCatalogFilename } from '../../../catalog/catalogUtils';\nimport {\n RepositoryDao,\n ScaffolderTaskDao,\n TaskLocationsDao,\n} from '../../../database/repositoryDao';\nimport { Components } from '../../../generated/openapi';\nimport { GithubApiService } from '../../../github';\nimport { HandlerResponse } from '../handlers';\n\ninterface ScaffolderEvent {\n id: number;\n isTaskRecoverable: boolean;\n taskId: string;\n body: {\n message: string;\n stepId?: string;\n status?: string;\n [key: string]: any;\n };\n type: 'log' | 'completion' | 'error';\n createdAt: string;\n error?: any;\n}\n\nasync function* getEvents(\n taskId: string,\n scaffolderUrl: string,\n token: string,\n logger: LoggerService,\n): AsyncGenerator<ScaffolderEvent> {\n const url = `${scaffolderUrl}/v2/tasks/${taskId}/eventstream`;\n\n const eventSource = createEventSource({\n url,\n headers: {\n Authorization: `Bearer ${token}`,\n },\n });\n try {\n for await (const event of eventSource) {\n try {\n const data: ScaffolderEvent = JSON.parse(event.data);\n yield data;\n if (data.type === 'completion' || data.type === 'error') {\n break;\n }\n } catch (err) {\n logger.error('Failed to parse SSE event', err);\n }\n }\n } catch (err) {\n logger.error('SSE error', err);\n } finally {\n eventSource.close();\n }\n}\n\nexport async function processTaskEvents(\n taskId: string,\n scaffolderUrl: string,\n token: string,\n logger: LoggerService,\n taskLocationsDao: TaskLocationsDao,\n) {\n try {\n for await (const event of getEvents(taskId, scaffolderUrl, token, logger)) {\n if (event.type === 'log') {\n const message = event.body.message;\n const match = message.match(/Registering (.*) in the catalog/);\n if (match?.[1]) {\n await taskLocationsDao.addTaskLocation(taskId, match[1]);\n }\n }\n }\n } catch (e) {\n logger.error(`Failed to process events for task ${taskId}`, e);\n }\n}\n\nconst handlePullRequestUpdate = async (\n importReq: Components.Schemas.ImportRequest,\n logger: LoggerService,\n config: Config,\n githubApiService: GithubApiService,\n): Promise<Components.Schemas.Import> => {\n const url = importReq.repository.url;\n const owner = importReq.repository.organization;\n const repoName = importReq.repository.name;\n const prUrl = importReq.github?.pullRequest?.url;\n const prNumber = importReq.github?.pullRequest?.number;\n const prTitle = importReq.github?.pullRequest?.title;\n const prBody = importReq.github?.pullRequest?.body;\n const catalogInfoContent = importReq.catalogInfoContent;\n\n const result: Components.Schemas.Import = {\n repository: {\n organization: owner,\n url: url,\n name: repoName,\n },\n github: {\n pullRequest: {\n url: prUrl,\n number: prNumber,\n title: prTitle,\n body: prBody,\n catalogInfoContent: catalogInfoContent,\n },\n },\n approvalTool: importReq.approvalTool,\n };\n\n try {\n if (prNumber && prTitle && prBody) {\n await githubApiService.updatePullRequest(url, prNumber, prTitle, prBody);\n\n const prInfo = await githubApiService.getPullRequest(url, prNumber);\n\n // Update catalog info content in the pull request\n const gitUrl = gitUrlParse(url);\n const fileName = getCatalogFilename(config);\n if (catalogInfoContent && prInfo.prBranch) {\n await githubApiService.createOrUpdateFileInBranch(\n gitUrl.owner,\n gitUrl.name,\n prInfo.prBranch,\n fileName,\n catalogInfoContent,\n );\n }\n } else {\n logger.warn(`prNumber is undefined, skipping updatePullRequest`);\n }\n } catch (err) {\n logger.error(`Failed to update pull request ${prUrl}`, err);\n result.status = 'PR_ERROR';\n result.errors = [err];\n return result;\n }\n\n result.status = 'WAIT_PR_APPROVAL';\n return result;\n};\n\nexport const createTaskImportJobs = async (\n templateRef: string,\n discovery: DiscoveryService,\n logger: LoggerService,\n auth: AuthService,\n config: Config,\n repositoryDao: RepositoryDao,\n taskDao: ScaffolderTaskDao,\n taskLocationsDao: TaskLocationsDao,\n importRequests: Components.Schemas.ImportRequest[],\n githubApiService: GithubApiService,\n): Promise<\n HandlerResponse<Components.Schemas.Import[] | { errors: string[] }>\n> => {\n if (importRequests.length === 0) {\n logger.debug('Missing import requests from request body');\n return {\n statusCode: 400,\n responseBody: [],\n };\n }\n\n const result: Components.Schemas.Import[] = [];\n\n const scaffolderUrl = await discovery.getBaseUrl('scaffolder');\n const { token } = await auth.getPluginRequestToken({\n onBehalfOf: await auth.getOwnServiceCredentials(),\n targetPluginId: 'scaffolder',\n });\n\n const executeTask = async (\n values: Record<string, any>,\n ): Promise<{ taskId: string; status: string; createdAt: string }> => {\n const response = await fetch(`${scaffolderUrl}/v2/tasks`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${token}`,\n },\n body: JSON.stringify({\n templateRef: `${templateRef}`,\n values: {\n repoUrl: values.repoUrl,\n owner: values.owner,\n ...values,\n },\n secrets: {},\n }),\n });\n\n if (!response.ok) {\n throw new Error(\n `Failed to start scaffolder task: ${response.status} ${response.statusText}`,\n );\n }\n\n const data = await response.json();\n const taskResp = await fetch(`${scaffolderUrl}/v2/tasks/${data.id}`, {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n });\n\n const task = await taskResp.json();\n return { taskId: data.id, status: task.status, createdAt: task.createdAt };\n };\n\n for (const importReq of importRequests) {\n const url = importReq.repository.url;\n const owner = importReq.repository.organization;\n const repoName = importReq.repository.name;\n if (importReq.github?.pullRequest?.url) {\n const updatedImport = await handlePullRequestUpdate(\n importReq,\n logger,\n config,\n githubApiService,\n );\n result.push(updatedImport);\n } else {\n try {\n // Create new task\n const gitProviderHost = new URL(importReq.repository.url).hostname;\n const normalizedUrl = `${gitProviderHost}?owner=${owner}&repo=${repoName}`;\n\n const scaffolderOptions = {\n name: repoName,\n organization: owner,\n repoUrl: normalizedUrl,\n branchName: `bulk-import-catalog-entity`,\n targetBranchName: importReq.repository.defaultBranch,\n gitProviderHost,\n };\n const { taskId, status, createdAt } =\n await executeTask(scaffolderOptions);\n\n const repositoryId = await repositoryDao.insertRepository(\n url,\n taskId,\n importReq.approvalTool ?? 'GIT',\n );\n await taskDao.insertTask({\n repositoryId,\n scaffolderOptions,\n taskId,\n executedAt: new Date(),\n });\n result.push({\n repository: {\n organization: owner,\n url,\n name: repoName,\n },\n status:\n `TASK_${status.toLocaleUpperCase()}` as Components.Schemas.TaskImportStatus,\n task: { taskId },\n lastUpdate: createdAt,\n approvalTool: importReq.approvalTool,\n });\n\n processTaskEvents(\n taskId,\n scaffolderUrl,\n token,\n logger,\n taskLocationsDao,\n );\n } catch (error: any) {\n logger.error(`Error processing import request for ${url}`, error);\n result.push({\n repository: {\n organization: owner,\n url,\n name: repoName,\n },\n status: 'TASK_FAILED',\n errors: [error.message],\n approvalTool: importReq.approvalTool,\n });\n }\n }\n }\n\n if (result.some(r => r.errors)) {\n return {\n statusCode: 202,\n responseBody: { errors: result.flatMap(r => r.errors || []) },\n };\n }\n\n return {\n statusCode: 202,\n responseBody: result,\n };\n};\n"],"names":["createEventSource","gitUrlParse","getCatalogFilename"],"mappings":"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"}
1
+ {"version":3,"file":"execute-template.cjs.js","sources":["../../../../src/service/handlers/import/execute-template.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 AuthService,\n DiscoveryService,\n LoggerService,\n} from '@backstage/backend-plugin-api';\nimport { Config } from '@backstage/config';\n\nimport { createEventSource } from 'eventsource-client';\nimport gitUrlParse from 'git-url-parse';\n\nimport { getCatalogFilename } from '../../../catalog/catalogUtils';\nimport {\n RepositoryDao,\n ScaffolderTaskDao,\n TaskLocationsDao,\n} from '../../../database/repositoryDao';\nimport { Components } from '../../../generated/openapi';\nimport { GithubApiService } from '../../../github';\nimport { HandlerResponse } from '../handlers';\nimport { sortImports } from './bulkImports';\n\ninterface ScaffolderEvent {\n id: number;\n isTaskRecoverable: boolean;\n taskId: string;\n body: {\n message: string;\n stepId?: string;\n status?: string;\n [key: string]: any;\n };\n type: 'log' | 'completion' | 'error';\n createdAt: string;\n error?: any;\n}\n\nasync function* getEvents(\n taskId: string,\n scaffolderUrl: string,\n token: string,\n logger: LoggerService,\n): AsyncGenerator<ScaffolderEvent> {\n const url = `${scaffolderUrl}/v2/tasks/${taskId}/eventstream`;\n\n const eventSource = createEventSource({\n url,\n headers: {\n Authorization: `Bearer ${token}`,\n },\n });\n try {\n for await (const event of eventSource) {\n try {\n const data: ScaffolderEvent = JSON.parse(event.data);\n yield data;\n if (data.type === 'completion' || data.type === 'error') {\n break;\n }\n } catch (err) {\n logger.error('Failed to parse SSE event', err);\n }\n }\n } catch (err) {\n logger.error('SSE error', err);\n } finally {\n eventSource.close();\n }\n}\n\nexport async function processTaskEvents(\n taskId: string,\n scaffolderUrl: string,\n token: string,\n logger: LoggerService,\n taskLocationsDao: TaskLocationsDao,\n) {\n try {\n for await (const event of getEvents(taskId, scaffolderUrl, token, logger)) {\n if (event.type === 'log') {\n const message = event.body.message;\n const match = message.match(/Registering (.*) in the catalog/);\n if (match?.[1]) {\n await taskLocationsDao.addTaskLocation(taskId, match[1]);\n }\n }\n }\n } catch (e) {\n logger.error(`Failed to process events for task ${taskId}`, e);\n }\n}\n\nconst handlePullRequestUpdate = async (\n importReq: Components.Schemas.ImportRequest,\n logger: LoggerService,\n config: Config,\n githubApiService: GithubApiService,\n): Promise<Components.Schemas.Import> => {\n const url = importReq.repository.url;\n const owner = importReq.repository.organization;\n const repoName = importReq.repository.name;\n const prUrl = importReq.github?.pullRequest?.url;\n const prNumber = importReq.github?.pullRequest?.number;\n const prTitle = importReq.github?.pullRequest?.title;\n const prBody = importReq.github?.pullRequest?.body;\n const catalogInfoContent = importReq.catalogInfoContent;\n\n const result: Components.Schemas.Import = {\n repository: {\n organization: owner,\n url: url,\n name: repoName,\n },\n github: {\n pullRequest: {\n url: prUrl,\n number: prNumber,\n title: prTitle,\n body: prBody,\n catalogInfoContent: catalogInfoContent,\n },\n },\n approvalTool: importReq.approvalTool,\n };\n\n try {\n if (prNumber && prTitle && prBody) {\n await githubApiService.updatePullRequest(url, prNumber, prTitle, prBody);\n\n const prInfo = await githubApiService.getPullRequest(url, prNumber);\n\n // Update catalog info content in the pull request\n const gitUrl = gitUrlParse(url);\n const fileName = getCatalogFilename(config);\n if (catalogInfoContent && prInfo.prBranch) {\n await githubApiService.createOrUpdateFileInBranch(\n gitUrl.owner,\n gitUrl.name,\n prInfo.prBranch,\n fileName,\n catalogInfoContent,\n );\n }\n } else {\n logger.warn(`prNumber is undefined, skipping updatePullRequest`);\n }\n } catch (err) {\n logger.error(`Failed to update pull request ${prUrl}`, err);\n result.status = 'PR_ERROR';\n result.errors = [(err as Error).message];\n return result;\n }\n\n result.status = 'WAIT_PR_APPROVAL';\n return result;\n};\n\nexport const createTaskImportJobs = async (\n templateRef: string,\n discovery: DiscoveryService,\n logger: LoggerService,\n auth: AuthService,\n config: Config,\n repositoryDao: RepositoryDao<'repositories'>,\n taskDao: ScaffolderTaskDao,\n taskLocationsDao: TaskLocationsDao,\n importRequests: Components.Schemas.ImportRequest[],\n githubApiService: GithubApiService,\n): Promise<HandlerResponse<Components.Schemas.Import[]>> => {\n if (importRequests.length === 0) {\n logger.debug('Missing import requests from request body');\n return {\n statusCode: 400,\n responseBody: [],\n };\n }\n\n const result: Components.Schemas.Import[] = [];\n\n const scaffolderUrl = await discovery.getBaseUrl('scaffolder');\n const { token } = await auth.getPluginRequestToken({\n onBehalfOf: await auth.getOwnServiceCredentials(),\n targetPluginId: 'scaffolder',\n });\n\n const executeTask = async (\n values: Record<string, any>,\n ): Promise<{ taskId: string; status: string; createdAt: string }> => {\n const response = await fetch(`${scaffolderUrl}/v2/tasks`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${token}`,\n },\n body: JSON.stringify({\n templateRef: `${templateRef}`,\n values: {\n repoUrl: values.repoUrl,\n owner: values.owner,\n ...values,\n },\n secrets: {},\n }),\n });\n\n if (!response.ok) {\n throw new Error(\n `Failed to start scaffolder task: ${response.status} ${response.statusText}`,\n );\n }\n\n const data = await response.json();\n const taskResp = await fetch(`${scaffolderUrl}/v2/tasks/${data.id}`, {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n });\n\n const task = await taskResp.json();\n return { taskId: data.id, status: task.status, createdAt: task.createdAt };\n };\n\n for (const importReq of importRequests) {\n const url = importReq.repository.url;\n const owner = importReq.repository.organization;\n const repoName = importReq.repository.name;\n if (importReq.github?.pullRequest?.url) {\n const updatedImport = await handlePullRequestUpdate(\n importReq,\n logger,\n config,\n githubApiService,\n );\n result.push(updatedImport);\n } else {\n try {\n // Create new task\n const gitProviderHost = new URL(importReq.repository.url).hostname;\n const normalizedUrl = `${gitProviderHost}?owner=${owner}&repo=${repoName}`;\n\n const scaffolderOptions = {\n name: repoName,\n organization: owner,\n repoUrl: normalizedUrl,\n branchName: `bulk-import-catalog-entity`,\n targetBranchName: importReq.repository.defaultBranch,\n gitProviderHost,\n };\n const { taskId, status, createdAt } =\n await executeTask(scaffolderOptions);\n\n const repositoryId = await repositoryDao.insertRepository(\n url,\n taskId,\n importReq.approvalTool ?? 'GIT',\n );\n await taskDao.insertTask({\n repositoryId,\n scaffolderOptions,\n taskId,\n executedAt: new Date(),\n });\n result.push({\n repository: {\n organization: owner,\n url,\n name: repoName,\n },\n status:\n `TASK_${status.toLocaleUpperCase()}` as Components.Schemas.TaskImportStatus,\n task: { taskId },\n lastUpdate: createdAt,\n approvalTool: importReq.approvalTool,\n });\n\n processTaskEvents(\n taskId,\n scaffolderUrl,\n token,\n logger,\n taskLocationsDao,\n );\n } catch (error: any) {\n logger.error(`Error processing import request for ${url}`, error);\n result.push({\n repository: {\n organization: owner,\n url,\n name: repoName,\n },\n status: 'TASK_FAILED',\n errors: [error.message],\n approvalTool: importReq.approvalTool,\n });\n }\n }\n }\n\n sortImports(result);\n\n return {\n statusCode: 202,\n responseBody: result,\n };\n};\n"],"names":["createEventSource","gitUrlParse","getCatalogFilename","sortImports"],"mappings":"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"}
@@ -3,6 +3,7 @@
3
3
  var gitUrlParse = require('git-url-parse');
4
4
  var handlers = require('../handlers.cjs.js');
5
5
  require('@backstage/errors');
6
+ require('@red-hat-developer-hub/backstage-plugin-orchestrator-common');
6
7
  require('@backstage/plugin-permission-common');
7
8
  require('@red-hat-developer-hub/backstage-plugin-bulk-import-common');
8
9
  require('just-kebab-case');
@@ -1 +1 @@
1
- {"version":3,"file":"repositories.cjs.js","sources":["../../../../src/service/handlers/repository/repositories.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 { LoggerService } from '@backstage/backend-plugin-api';\nimport type { Config } from '@backstage/config';\n\nimport gitUrlParse from 'git-url-parse';\n\nimport { CatalogHttpClient } from '../../../catalog/catalogHttpClient';\nimport type { Components } from '../../../generated/openapi';\nimport type {\n GithubApiService,\n GithubRepositoryResponse,\n} from '../../../github';\nimport { GitlabApiService, GitlabRepositoryResponse } from '../../../gitlab';\nimport {\n DefaultPageNumber,\n DefaultPageSize,\n type HandlerResponse,\n} from '../handlers';\nimport { getImportStatusFromLocations } from '../import';\n\nexport async function findAllRepositories(\n deps: {\n logger: LoggerService;\n config: Config;\n gitApiService: GithubApiService | GitlabApiService;\n catalogHttpClient: CatalogHttpClient;\n },\n reqParams?: {\n approvalTool?: string;\n search?: string;\n checkStatus?: boolean;\n pageNumber?: number;\n pageSize?: number;\n },\n): Promise<HandlerResponse<Components.Schemas.RepositoryList>> {\n const search = reqParams?.search;\n const checkStatus = reqParams?.checkStatus ?? false;\n const pageNumber = reqParams?.pageNumber ?? DefaultPageNumber;\n const pageSize = reqParams?.pageSize ?? DefaultPageSize;\n deps.logger.debug(\n `Getting all repositories - (search,page,size)=('${\n search ?? ''\n }',${pageNumber},${pageSize})..`,\n );\n\n const repos = await deps.gitApiService\n .getRepositoriesFromIntegrations(search, pageNumber, pageSize)\n .then(response => formatResponse(deps, response, checkStatus));\n\n return repos;\n}\n\nexport async function findRepositoriesByOrganization(\n deps: {\n logger: LoggerService;\n config: Config;\n gitApiService: GithubApiService | GitlabApiService;\n catalogHttpClient: CatalogHttpClient;\n },\n orgName: string,\n search?: string,\n checkStatus: boolean = false,\n pageNumber: number = DefaultPageNumber,\n pageSize: number = DefaultPageSize,\n): Promise<HandlerResponse<Components.Schemas.RepositoryList>> {\n deps.logger.debug(\n `Getting all repositories for org \"${orgName}\" - (search,page,size)=(${search},${pageNumber},${pageSize})..`,\n );\n\n const glReposByOrg = await deps.gitApiService\n .getOrgRepositoriesFromIntegrations(orgName, search, pageNumber, pageSize)\n .then(response => formatResponse(deps, response, checkStatus));\n\n return glReposByOrg;\n}\n\nfunction sortRepos(repoList: Components.Schemas.Repository[]) {\n // sorting the output to make it deterministic and easy to navigate in the UI\n repoList.sort((a, b) => {\n if (a.name === undefined && b.name === undefined) {\n return 0;\n }\n if (a.name === undefined) {\n return -1;\n }\n if (b.name === undefined) {\n return 1;\n }\n return a.name.localeCompare(b.name);\n });\n}\n\ntype ImportStatus =\n | { status: Components.Schemas.ImportStatus; lastUpdate?: string }\n | null\n | undefined;\n\nasync function formatResponse(\n deps: {\n logger: LoggerService;\n config: Config;\n gitApiService: GithubApiService | GitlabApiService;\n catalogHttpClient: CatalogHttpClient;\n },\n allReposAccessible: GithubRepositoryResponse | GitlabRepositoryResponse,\n checkStatus: boolean,\n) {\n const errorList =\n allReposAccessible.errors\n ?.map(err => err.error?.message)\n ?.filter(msg => msg) ?? [];\n if (allReposAccessible.repositories?.length === 0 && errorList.length > 0) {\n return {\n statusCode: 500,\n responseBody: {\n errors: errorList,\n },\n };\n }\n\n let catalogLocations: Iterable<string> = [];\n if (checkStatus) {\n catalogLocations = (\n await deps.catalogHttpClient.listCatalogUrlLocations()\n ).uniqueCatalogUrlLocations.keys();\n }\n const repoList: Components.Schemas.Repository[] = [];\n for (const repo of allReposAccessible.repositories) {\n const gitUrl = gitUrlParse(repo.html_url);\n const errors: string[] = [];\n let importStatus: ImportStatus;\n if (checkStatus) {\n importStatus = await getImportStatusFromLocations(\n deps,\n repo.html_url,\n catalogLocations,\n repo.default_branch,\n ).catch((error: any) => {\n errors.push(error.message);\n return undefined;\n });\n }\n const repoUpdatedAt = repo.updated_at ?? undefined;\n repoList.push({\n id: `${gitUrl.organization}/${repo.name}`,\n name: repo.name,\n organization: gitUrl.organization,\n url: repo.html_url,\n defaultBranch: repo.default_branch,\n importStatus: importStatus?.status,\n lastUpdate: importStatus?.lastUpdate ?? repoUpdatedAt,\n errors: errors,\n });\n }\n\n sortRepos(repoList);\n\n return {\n statusCode: 200,\n responseBody: {\n errors: errorList,\n repositories: repoList,\n totalCount: allReposAccessible.totalCount,\n },\n };\n}\n"],"names":["DefaultPageNumber","DefaultPageSize","gitUrlParse","importStatus","getImportStatusFromLocations"],"mappings":"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"}
1
+ {"version":3,"file":"repositories.cjs.js","sources":["../../../../src/service/handlers/repository/repositories.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 { LoggerService } from '@backstage/backend-plugin-api';\nimport type { Config } from '@backstage/config';\n\nimport gitUrlParse from 'git-url-parse';\n\nimport { CatalogHttpClient } from '../../../catalog/catalogHttpClient';\nimport type { Components } from '../../../generated/openapi';\nimport type {\n GithubApiService,\n GithubRepositoryResponse,\n} from '../../../github';\nimport { GitlabApiService, GitlabRepositoryResponse } from '../../../gitlab';\nimport {\n DefaultPageNumber,\n DefaultPageSize,\n type HandlerResponse,\n} from '../handlers';\nimport { getImportStatusFromLocations } from '../import';\n\nexport async function findAllRepositories(\n deps: {\n logger: LoggerService;\n config: Config;\n gitApiService: GithubApiService | GitlabApiService;\n catalogHttpClient: CatalogHttpClient;\n },\n reqParams?: {\n approvalTool?: string;\n search?: string;\n checkStatus?: boolean;\n pageNumber?: number;\n pageSize?: number;\n },\n): Promise<HandlerResponse<Components.Schemas.RepositoryList>> {\n const search = reqParams?.search;\n const checkStatus = reqParams?.checkStatus ?? false;\n const pageNumber = reqParams?.pageNumber ?? DefaultPageNumber;\n const pageSize = reqParams?.pageSize ?? DefaultPageSize;\n deps.logger.debug(\n `Getting all repositories - (search,page,size)=('${\n search ?? ''\n }',${pageNumber},${pageSize})..`,\n );\n\n const repos = await deps.gitApiService\n .getRepositoriesFromIntegrations(search, pageNumber, pageSize)\n .then(response => formatResponse(deps, response, checkStatus));\n\n return repos;\n}\n\nexport async function findRepositoriesByOrganization(\n deps: {\n logger: LoggerService;\n config: Config;\n gitApiService: GithubApiService | GitlabApiService;\n catalogHttpClient: CatalogHttpClient;\n },\n orgName: string,\n search?: string,\n checkStatus: boolean = false,\n pageNumber: number = DefaultPageNumber,\n pageSize: number = DefaultPageSize,\n): Promise<HandlerResponse<Components.Schemas.RepositoryList>> {\n deps.logger.debug(\n `Getting all repositories for org \"${orgName}\" - (search,page,size)=(${search},${pageNumber},${pageSize})..`,\n );\n\n const glReposByOrg = await deps.gitApiService\n .getOrgRepositoriesFromIntegrations(orgName, search, pageNumber, pageSize)\n .then(response => formatResponse(deps, response, checkStatus));\n\n return glReposByOrg;\n}\n\nfunction sortRepos(repoList: Components.Schemas.Repository[]) {\n // sorting the output to make it deterministic and easy to navigate in the UI\n repoList.sort((a, b) => {\n if (a.name === undefined && b.name === undefined) {\n return 0;\n }\n if (a.name === undefined) {\n return -1;\n }\n if (b.name === undefined) {\n return 1;\n }\n return a.name.localeCompare(b.name);\n });\n}\n\ntype ImportStatus =\n | { status: Components.Schemas.ImportStatus; lastUpdate?: string }\n | null\n | undefined;\n\nasync function formatResponse(\n deps: {\n logger: LoggerService;\n config: Config;\n gitApiService: GithubApiService | GitlabApiService;\n catalogHttpClient: CatalogHttpClient;\n },\n allReposAccessible: GithubRepositoryResponse | GitlabRepositoryResponse,\n checkStatus: boolean,\n) {\n const errorList =\n allReposAccessible.errors\n ?.map(err => err.error?.message)\n ?.filter(msg => msg) ?? [];\n if (allReposAccessible.repositories?.length === 0 && errorList.length > 0) {\n return {\n statusCode: 500,\n responseBody: {\n errors: errorList,\n },\n };\n }\n\n let catalogLocations: Iterable<string> = [];\n if (checkStatus) {\n catalogLocations = (\n await deps.catalogHttpClient.listCatalogUrlLocations()\n ).uniqueCatalogUrlLocations.keys();\n }\n const repoList: Components.Schemas.Repository[] = [];\n for (const repo of allReposAccessible.repositories) {\n const gitUrl = gitUrlParse(repo.html_url);\n const errors: string[] = [];\n let importStatus: ImportStatus;\n if (checkStatus) {\n importStatus = await getImportStatusFromLocations(\n deps,\n repo.html_url,\n catalogLocations,\n repo.default_branch,\n ).catch((error: any) => {\n errors.push(error.message);\n return undefined;\n });\n }\n const repoUpdatedAt = repo.updated_at ?? undefined;\n repoList.push({\n id: `${gitUrl.organization}/${repo.name}`,\n name: repo.name,\n organization: gitUrl.organization,\n url: repo.html_url,\n defaultBranch: repo.default_branch,\n importStatus: importStatus?.status,\n lastUpdate: importStatus?.lastUpdate ?? repoUpdatedAt,\n errors: errors,\n });\n }\n\n sortRepos(repoList);\n\n return {\n statusCode: 200,\n responseBody: {\n errors: errorList,\n repositories: repoList,\n totalCount: allReposAccessible.totalCount,\n },\n };\n}\n"],"names":["DefaultPageNumber","DefaultPageSize","gitUrlParse","importStatus","getImportStatusFromLocations"],"mappings":"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"}
@@ -1,6 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var rootHttpRouter = require('@backstage/backend-defaults/rootHttpRouter');
4
+ var errors = require('@backstage/errors');
4
5
  var pluginPermissionNode = require('@backstage/plugin-permission-node');
5
6
  var formats = require('ajv-formats/dist/formats');
6
7
  var express = require('express');
@@ -18,10 +19,10 @@ require('luxon');
18
19
  var githubApiService = require('../github/githubApiService.cjs.js');
19
20
  var gitlabApiService = require('../gitlab/gitlabApiService.cjs.js');
20
21
  var auth = require('../helpers/auth.cjs.js');
21
- require('@backstage/errors');
22
22
  var utils = require('../helpers/utils.cjs.js');
23
23
  var auditorUtils = require('../helpers/auditorUtils.cjs.js');
24
24
  var bulkImports = require('./handlers/import/bulkImports.cjs.js');
25
+ var executeOrchestratorWorkflow = require('./handlers/import/execute-orchestrator-workflow.cjs.js');
25
26
  var executeTemplate = require('./handlers/import/execute-template.cjs.js');
26
27
  var organizations = require('./handlers/organization/organizations.cjs.js');
27
28
  var ping = require('./handlers/ping/ping.cjs.js');
@@ -39,12 +40,16 @@ var Operations;
39
40
  Operations2.FIND_REPOSITORIES_BY_ORGANIZATION = "findRepositoriesByOrganization";
40
41
  Operations2.FIND_ALL_IMPORTS = "findAllImports";
41
42
  Operations2.FIND_ALL_TASK_IMPORTS = "findAllTaskImports";
43
+ Operations2.FIND_ALL_ORCHESTRATOR_WORKFLOW_IMPORTS = "findAllOrchestratorWorkflowImports";
42
44
  Operations2.CREATE_IMPORT_JOBS = "createImportJobs";
43
45
  Operations2.CREATE_TASK_IMPORT_JOBS = "createTaskImportJobs";
46
+ Operations2.CREATE_ORCHESTRATOR_WORKFLOW_JOBS = "createOrchestratorWorkflowJobs";
44
47
  Operations2.FIND_IMPORT_STATUS_BY_REPO = "findImportStatusByRepo";
45
48
  Operations2.FIND_TASK_IMPORT_STATUS_BY_REPO = "findTaskImportStatusByRepo";
49
+ Operations2.FIND_ORCHESTRATOR_IMPORT_STATUS_BY_REPO = "findOrchestratorImportStatusByRepo";
46
50
  Operations2.DELETE_IMPORT_BY_REPO = "deleteImportByRepo";
47
51
  Operations2.DELETE_TASK_IMPORT_BY_REPO = "deleteTaskImportByRepo";
52
+ Operations2.DELETE_ORCHESTRATOR_IMPORT_BY_REPO = "deleteOrchestratorImportByRepo";
48
53
  })(Operations || (Operations = {}));
49
54
  async function createRouter(options) {
50
55
  const {
@@ -60,9 +65,15 @@ async function createRouter(options) {
60
65
  database
61
66
  } = options;
62
67
  const knex = await migration.migrate(database);
63
- const repositoryDao$1 = new repositoryDao.RepositoryDao(knex, logger);
68
+ const repositoryDao$1 = new repositoryDao.RepositoryDao(knex, logger, "repositories");
64
69
  const taskDao = new repositoryDao.ScaffolderTaskDao(knex);
65
70
  const taskLocationsDao = new repositoryDao.TaskLocationsDao(knex);
71
+ const orchestratorRepositoryDao = new repositoryDao.RepositoryDao(
72
+ knex,
73
+ logger,
74
+ "orchestrator_repositories"
75
+ );
76
+ const orchestratorWorkflowDao = new repositoryDao.OrchestratorWorkflowDao(knex);
66
77
  const githubApiService$1 = new githubApiService.GithubApiService(logger, config, cache);
67
78
  const gitlabApiService$1 = new gitlabApiService.GitlabApiService(logger, config, cache);
68
79
  const catalogHttpClient$1 = new catalogHttpClient.CatalogHttpClient({
@@ -95,6 +106,9 @@ async function createRouter(options) {
95
106
  if (templateRef) {
96
107
  finalTemplateRef = utils.getImportTemplateRef(templateRef);
97
108
  }
109
+ const orchestratorWorkflowId = config.getOptionalString(
110
+ "bulkImport.orchestratorWorkflow"
111
+ );
98
112
  await api.init();
99
113
  api.register(
100
114
  Operations.PING,
@@ -270,6 +284,43 @@ async function createRouter(options) {
270
284
  return res.status(200).json(responseBody);
271
285
  }
272
286
  );
287
+ api.register(
288
+ Operations.FIND_ALL_ORCHESTRATOR_WORKFLOW_IMPORTS,
289
+ async (c, req, res) => {
290
+ const { pageNumber, pageSize, search, sortColumn, sortOrder } = getFindImportsParams(c);
291
+ const imports = [];
292
+ const repositories = await orchestratorRepositoryDao.findRepositories(
293
+ pageNumber,
294
+ pageSize,
295
+ search
296
+ );
297
+ const token = getBearerTokenFromReq(req);
298
+ for (const repo of repositories.data) {
299
+ const response = await bulkImports.findOrchestratorImportStatusByRepo(
300
+ {
301
+ logger,
302
+ orchestratorRepositoryDao,
303
+ orchestratorWorkflowDao,
304
+ discovery
305
+ },
306
+ repo.url,
307
+ token,
308
+ true
309
+ );
310
+ if (response.responseBody) {
311
+ imports.push(response.responseBody);
312
+ }
313
+ }
314
+ bulkImports.sortImports(imports, sortColumn, sortOrder);
315
+ const responseBody = {
316
+ imports,
317
+ totalCount: repositories.total,
318
+ page: pageNumber || 1,
319
+ size: pageSize || 5
320
+ };
321
+ return res.status(200).json(responseBody);
322
+ }
323
+ );
273
324
  api.register(
274
325
  Operations.CREATE_IMPORT_JOBS,
275
326
  async (c, _req, res) => {
@@ -319,6 +370,28 @@ async function createRouter(options) {
319
370
  return res.status(response.statusCode).json(response.responseBody);
320
371
  }
321
372
  );
373
+ api.register(
374
+ Operations.CREATE_ORCHESTRATOR_WORKFLOW_JOBS,
375
+ async (c, req, res) => {
376
+ if (!orchestratorWorkflowId) {
377
+ throw new Error(
378
+ `Missing required config value: 'bulkImport.orchestratorWorkflow'`
379
+ );
380
+ }
381
+ const token = getBearerTokenFromReq(req);
382
+ const response = await executeOrchestratorWorkflow.createWorkflowImportJobs({
383
+ orchestratorWorkflowId,
384
+ discovery,
385
+ token,
386
+ requestBody: c.request.requestBody,
387
+ orchestratorWorkflowDao,
388
+ orchestratorRepositoryDao,
389
+ githubApiService: githubApiService$1,
390
+ gitlabApiService: gitlabApiService$1
391
+ });
392
+ res.status(response.statusCode).json(response.responseBody);
393
+ }
394
+ );
322
395
  api.register(
323
396
  Operations.FIND_TASK_IMPORT_STATUS_BY_REPO,
324
397
  async (c, _req, res) => {
@@ -370,6 +443,29 @@ async function createRouter(options) {
370
443
  return res.status(response.statusCode).json(response.responseBody);
371
444
  }
372
445
  );
446
+ api.register(
447
+ Operations.FIND_ORCHESTRATOR_IMPORT_STATUS_BY_REPO,
448
+ async (c, req, res) => {
449
+ const q = {
450
+ ...c.request.query
451
+ };
452
+ if (!q.repo?.trim()) {
453
+ throw new Error("missing or blank parameter");
454
+ }
455
+ const token = getBearerTokenFromReq(req);
456
+ const response = await bulkImports.findOrchestratorImportStatusByRepo(
457
+ {
458
+ logger,
459
+ orchestratorRepositoryDao,
460
+ orchestratorWorkflowDao,
461
+ discovery
462
+ },
463
+ q.repo,
464
+ token
465
+ );
466
+ return res.status(response.statusCode).json(response.responseBody);
467
+ }
468
+ );
373
469
  api.register(
374
470
  Operations.DELETE_TASK_IMPORT_BY_REPO,
375
471
  async (c, _req, res) => {
@@ -379,7 +475,7 @@ async function createRouter(options) {
379
475
  if (!q.repo?.trim()) {
380
476
  throw new Error('missing or blank "repo" parameter');
381
477
  }
382
- const response = await bulkImports.deleteTaskImportByRepo(
478
+ const response = await bulkImports.deleteRepositoryRecord(
383
479
  {
384
480
  logger,
385
481
  dao: repositoryDao$1
@@ -411,6 +507,25 @@ async function createRouter(options) {
411
507
  return res.status(response.statusCode).json(response.responseBody);
412
508
  }
413
509
  );
510
+ api.register(
511
+ Operations.DELETE_ORCHESTRATOR_IMPORT_BY_REPO,
512
+ async (c, _req, res) => {
513
+ const q = {
514
+ ...c.request.query
515
+ };
516
+ if (!q.repo?.trim()) {
517
+ throw new Error('missing or blank "repo" parameter');
518
+ }
519
+ const response = await bulkImports.deleteRepositoryRecord(
520
+ {
521
+ logger,
522
+ dao: orchestratorRepositoryDao
523
+ },
524
+ q.repo
525
+ );
526
+ return res.status(response.statusCode).json(response.responseBody);
527
+ }
528
+ );
414
529
  const router = express.Router();
415
530
  router.use(express__default.default.json());
416
531
  const permissionIntegrationRouter = pluginPermissionNode.createPermissionIntegrationRouter({
@@ -478,6 +593,7 @@ async function createAuditorEventByOperationId(operationId, req, auditor) {
478
593
  }
479
594
  case Operations.FIND_ALL_IMPORTS:
480
595
  case Operations.FIND_ALL_TASK_IMPORTS:
596
+ case Operations.FIND_ALL_ORCHESTRATOR_WORKFLOW_IMPORTS:
481
597
  auditorEvent = await auditorUtils.auditCreateEvent(auditor, "import-read", req, {
482
598
  queryType: req.query.search ? "by-query" : "all",
483
599
  search: req.query.search
@@ -485,19 +601,14 @@ async function createAuditorEventByOperationId(operationId, req, auditor) {
485
601
  break;
486
602
  case Operations.CREATE_IMPORT_JOBS:
487
603
  case Operations.CREATE_TASK_IMPORT_JOBS:
604
+ case Operations.CREATE_ORCHESTRATOR_WORKFLOW_JOBS:
488
605
  auditorEvent = await auditorUtils.auditCreateEvent(auditor, "import-write", req, {
489
606
  actionType: "create"
490
607
  });
491
608
  break;
492
609
  case Operations.FIND_IMPORT_STATUS_BY_REPO:
493
- auditorEvent = await auditorUtils.auditCreateEvent(
494
- auditor,
495
- "import-status-read",
496
- req,
497
- { queryType: "by-query", repo: req.query.repo }
498
- );
499
- break;
500
610
  case Operations.FIND_TASK_IMPORT_STATUS_BY_REPO:
611
+ case Operations.FIND_ORCHESTRATOR_IMPORT_STATUS_BY_REPO:
501
612
  auditorEvent = await auditorUtils.auditCreateEvent(
502
613
  auditor,
503
614
  "import-status-read",
@@ -507,6 +618,7 @@ async function createAuditorEventByOperationId(operationId, req, auditor) {
507
618
  break;
508
619
  case Operations.DELETE_IMPORT_BY_REPO:
509
620
  case Operations.DELETE_TASK_IMPORT_BY_REPO:
621
+ case Operations.DELETE_ORCHESTRATOR_IMPORT_BY_REPO:
510
622
  auditorEvent = await auditorUtils.auditCreateEvent(auditor, "import-write", req, {
511
623
  actionType: "delete",
512
624
  repository: req.query.repo
@@ -553,6 +665,13 @@ function getFindImportsParams(c) {
553
665
  sortOrder: q.sortOrder
554
666
  };
555
667
  }
668
+ function getBearerTokenFromReq(req) {
669
+ const header = req.header("authorization") ?? req.headers.authorization;
670
+ if (header?.startsWith(`Bearer `)) {
671
+ return header.replace("Bearer ", "");
672
+ }
673
+ throw new errors.InputError(`Request provided without token`);
674
+ }
556
675
 
557
676
  exports.createRouter = createRouter;
558
677
  //# sourceMappingURL=router.cjs.js.map