-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathrepositories.ts
More file actions
95 lines (83 loc) · 3.93 KB
/
repositories.ts
File metadata and controls
95 lines (83 loc) · 3.93 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
import type { Project, Repository } from '@cpn-console/hooks'
import type { VaultProjectApi } from '@cpn-console/vault-plugin/types/vault-project-api.js'
import type { CondensedProjectSchema, ProjectSchema } from '@gitbeaker/rest'
import type { GitlabProjectApi } from './class.js'
import { shallowEqual } from '@cpn-console/shared'
import { pluginManagedTopic } from './class.js'
import { provisionMirror } from './project.js'
import { infraAppsRepoName, internalMirrorRepoName } from './utils.js'
interface ProjectMirrorCreds {
botAccount: string
token: string
}
export async function ensureRepositories(gitlabApi: GitlabProjectApi, project: Project, vaultApi: VaultProjectApi, projectMirrorCreds: ProjectMirrorCreds) {
console.log(`[GITLAB] ensureRepositories`)
const specialRepos = await gitlabApi.getSpecialRepositories()
const gitlabRepositories = await gitlabApi.listRepositories()
const promises: Promise<any>[] = [
// delete excess repositories
...gitlabRepositories
.filter(gitlabRepository => (
!specialRepos.includes(gitlabRepository.name)
&& !gitlabRepository.topics?.includes(pluginManagedTopic)
&& !project.repositories.some(repo => repo.internalRepoName === gitlabRepository.name)))
.map(gitlabRepository => gitlabApi.deleteRepository(gitlabRepository.id, gitlabRepository.path_with_namespace)),
// create missing repositories
...project.repositories.map(repo => ensureRepositoryExists(gitlabRepositories, repo, gitlabApi, projectMirrorCreds, vaultApi)),
]
if (!gitlabRepositories.some(repo => repo.name === infraAppsRepoName)) {
promises.push(
gitlabApi.createEmptyProjectRepository({ repoName: infraAppsRepoName, clone: false }),
)
}
if (!gitlabRepositories.some(repo => repo.name === internalMirrorRepoName)) {
promises.push(
gitlabApi.createEmptyProjectRepository({ repoName: internalMirrorRepoName, clone: false })
.then(mirrorRepo => provisionMirror(mirrorRepo.id)),
)
}
await Promise.all(promises)
}
const urnRegexp = /:\/\/(.*)/s
async function ensureRepositoryExists(gitlabRepositories: CondensedProjectSchema[], repository: Repository, gitlabApi: GitlabProjectApi, projectMirrorCreds: ProjectMirrorCreds, vaultApi: VaultProjectApi) {
console.log(`[GITLAB] ensureRepositoryExists`)
const gitlabRepository: CondensedProjectSchema | ProjectSchema | void = gitlabRepositories.find(gitlabRepository => gitlabRepository.name === repository.internalRepoName)
const externalRepoUrn = repository.externalRepoUrl.split(urnRegexp)[1]
const vaultCredsPath = `${repository.internalRepoName}-mirror`
const currentVaultSecret = await vaultApi.read(vaultCredsPath, { throwIfNoEntry: false })
if (!gitlabRepository) {
await gitlabApi.createEmptyProjectRepository({
repoName: repository.internalRepoName,
description: undefined,
clone: !!repository.externalRepoUrl,
})
}
if (!repository.externalRepoUrl) {
return currentVaultSecret && vaultApi.destroy(vaultCredsPath)
}
let gitInputUser: string | undefined
let gitInputPassword: string | undefined
if (currentVaultSecret?.data) {
gitInputUser = currentVaultSecret.data.GIT_INPUT_USER
gitInputPassword = currentVaultSecret.data.GIT_INPUT_PASSWORD
}
const internalRepoUrl = await gitlabApi.getInternalRepoUrl(repository.internalRepoName)
const mirrorSecretData = {
GIT_INPUT_URL: externalRepoUrn,
GIT_INPUT_USER: repository.isPrivate
? (repository.newCreds?.username || gitInputUser)
: undefined,
GIT_INPUT_PASSWORD: repository.isPrivate
? (repository.newCreds?.token || gitInputPassword)
: undefined,
GIT_OUTPUT_URL: internalRepoUrl.split(urnRegexp)[1],
GIT_OUTPUT_USER: projectMirrorCreds.botAccount,
GIT_OUTPUT_PASSWORD: projectMirrorCreds.token,
}
if (
!currentVaultSecret?.data
|| !shallowEqual(mirrorSecretData, currentVaultSecret.data)
) {
await vaultApi.write(mirrorSecretData, vaultCredsPath)
}
}