diff --git a/cmd/direct-transfer.js b/cmd/direct-transfer.js index ce448d1..75bf7a9 100644 --- a/cmd/direct-transfer.js +++ b/cmd/direct-transfer.js @@ -13,6 +13,8 @@ import readline from 'readline/promises'; import { writeFile } from 'fs/promises'; import { COPY_PROJECT_GROUP_DESC, SOURCE_REGIONS } from '../config.js'; import { getWithRetry } from './utils/requests.js'; +import Papa from 'papaparse'; +import fs from 'fs'; const HTTP_TIMEOUT_MS = 5 * 60 * 1000; // 5 minutes default @@ -158,11 +160,26 @@ class GitLabClient { return out; } + async getGroupPlaceholderCsv(groupId) { + const response = await this.client.get(`/groups/${groupId}/placeholder_reassignments`); + return response.data; + } + + async reassignGroupPlaceholder(groupId, form) { + const response = await this.client.postForm(`/groups/${groupId}/placeholder_reassignments`, form); + return response.data; + } + async getGroup(groupId) { const response = await this.client.get(`/groups/${groupId}`); return response.data; } + async syncUser(syncData) { + const response = await this.client.post(`https://otc-github-consolidated-broker.${syncData.destRegion}.devops.cloud.ibm.com/git-user-sync`, syncData); + return response.data; + } + async createBulkImport(importData) { const response = await this.client.post('/bulk_imports', importData); return response.data; @@ -657,6 +674,31 @@ async function directTransfer(options) { const finishedEntities = entities.filter(e => e.status === 'finished'); const failedEntities = entities.filter(e => e.status === 'failed'); + const getGroupPlaceholderCsvData = await destination.getGroupPlaceholderCsv(destinationGroupPath); + const groupPlaceholders = Papa.parse(getGroupPlaceholderCsvData, { header: true, skipEmptyLines: true }).data; + console.log(JSON.stringify(groupPlaceholders)); + + for (let i = 0; i < groupPlaceholders.length; i++) { + console.log(JSON.stringify(groupPlaceholders[i])); + const { username: destinationUsername } = await destination.syncUser({ + sourceRegion: options.sourceRegion, + destRegion: options.destRegion, + groupId: destinationGroupPath, + userId: groupPlaceholders[i]['Source user identifier'], + }); + console.log(destinationUsername); + groupPlaceholders[i]['GitLab username'] = destinationUsername; + } + + const csvForm = Papa.unparse(groupPlaceholders); + fs.writeFileSync('groupPlaceholders.csv', csvForm, 'utf8'); + const csvConfig = { + file : fs.createReadStream('groupPlaceholders.csv') + }; + + const reassignGroupPlaceholderData = await destination.reassignGroupPlaceholder(destinationGroupPath, csvConfig); + console.log(reassignGroupPlaceholderData); + if (importStatus === 'finished' && finishedEntities.length > 0) { console.log(`\nGroup migration completed successfully!`); console.log(`Migration Results:`); diff --git a/package-lock.json b/package-lock.json index e1e225e..2ad2ded 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,6 +16,7 @@ "commander": "^14.0.1", "json-to-tf": "^0.3.1", "ora": "^9.0.0", + "papaparse": "^5.5.3", "strip-ansi": "^7.1.2" }, "bin": { @@ -2146,6 +2147,7 @@ "is-interactive": "^2.0.0", "is-unicode-supported": "^2.1.0", "log-symbols": "^7.0.1", + "papaparse": "^5.5.3", "stdin-discarder": "^0.2.2", "string-width": "^8.1.0", "strip-ansi": "^7.1.2" @@ -2212,6 +2214,12 @@ "dev": true, "license": "BlueOak-1.0.0" }, + "node_modules/papaparse": { + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/papaparse/-/papaparse-5.5.3.tgz", + "integrity": "sha512-5QvjGxYVjxO59MGU2lHVYpRWBBtKHnlIAcSe1uNFCkkptUh63NFRj0FJQm7nR67puEruUci/ZkjmEFrjCAyP4A==", + "license": "MIT" + }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", diff --git a/package.json b/package.json index b4c1c50..0495789 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ "commander": "^14.0.1", "json-to-tf": "^0.3.1", "ora": "^9.0.0", + "papaparse": "^5.5.3", "strip-ansi": "^7.1.2" }, "bin": {