diff --git a/apps/server/src/resources/cluster/queries.ts b/apps/server/src/resources/cluster/queries.ts index dbd6aef20..756ff994a 100644 --- a/apps/server/src/resources/cluster/queries.ts +++ b/apps/server/src/resources/cluster/queries.ts @@ -133,16 +133,6 @@ export function getPublicClusters() { }) } -export async function getClusterNamesByZoneId(zoneId: string) { - const clusterNames = await prisma.cluster.findMany({ - where: { zoneId }, - select: { - label: true, - }, - }) - return clusterNames.map(({ label }) => label) -} - export function getClusterByLabel(label: Cluster['label']) { return prisma.cluster.findUnique({ where: { label } }) } diff --git a/apps/server/src/utils/hook-wrapper.ts b/apps/server/src/utils/hook-wrapper.ts index aee95e881..1636bf1c5 100644 --- a/apps/server/src/utils/hook-wrapper.ts +++ b/apps/server/src/utils/hook-wrapper.ts @@ -1,10 +1,10 @@ import type { Cluster, Kubeconfig, Project, ProjectRole, Zone } from '@prisma/client' -import type { ClusterObject, HookResult, KubeCluster, KubeUser, Project as ProjectPayload, RepoCreds, Repository, Store, ZoneObject } from '@cpn-console/hooks' +import type { ClusterObject, HookResult, KubeCluster, KubeUser, Project as ProjectPayload, RepoCreds, Repository, Store } from '@cpn-console/hooks' import { hooks } from '@cpn-console/hooks' import type { AsyncReturnType } from '@cpn-console/shared' import { ProjectAuthorized, getPermsByUserRoles, resourceListToDict } from '@cpn-console/shared' import { genericProxy } from './proxy.js' -import { archiveProject, getAdminPlugin, getClusterByIdOrThrow, getClusterNamesByZoneId, getClustersAssociatedWithProject, getHookProjectInfos, getHookRepository, getProjectStore, getZoneByIdOrThrow, saveProjectStore, updateProjectClusterHistory, updateProjectCreated, updateProjectFailed, updateProjectWarning } from '@/resources/queries-index.js' +import { archiveProject, getAdminPlugin, getClusterByIdOrThrow, getClustersAssociatedWithProject, getHookProjectInfos, getHookRepository, getProjectStore, getZoneByIdOrThrow, saveProjectStore, updateProjectClusterHistory, updateProjectCreated, updateProjectFailed, updateProjectWarning } from '@/resources/queries-index.js' import type { ConfigRecords } from '@/resources/project-service/business.js' import { dbToObj } from '@/resources/project-service/business.js' @@ -121,8 +121,7 @@ const user = { const zone = { upsert: async (zoneId: Zone['id']) => { - const zone: ZoneObject = await getZoneByIdOrThrow(zoneId) - zone.clusterNames = await getClusterNamesByZoneId(zoneId) + const zone = await getZoneByIdOrThrow(zoneId) const store = dbToObj(await getAdminPlugin()) return hooks.upsertZone.execute(zone, store) }, diff --git a/packages/hooks/src/hooks/index.ts b/packages/hooks/src/hooks/index.ts index c6a253e10..41fe06ff4 100644 --- a/packages/hooks/src/hooks/index.ts +++ b/packages/hooks/src/hooks/index.ts @@ -46,7 +46,6 @@ export interface ZoneObject { id: string slug: string argocdUrl: string - clusterNames?: string[] } export interface ClusterObject { diff --git a/plugins/argocd/src/cluster.ts b/plugins/argocd/src/cluster.ts index e0ab62050..da2f336d9 100644 --- a/plugins/argocd/src/cluster.ts +++ b/plugins/argocd/src/cluster.ts @@ -6,19 +6,11 @@ import { getConfig, getK8sApi } from './utils.js' export const upsertCluster: StepCall = async (payload) => { try { const cluster = payload.args - const { vault } = payload.apis if (cluster.label === inClusterLabel) { await deleteClusterSecret(cluster.secretName) } else { await createClusterSecret(cluster) } - const clusterData = { - name: cluster.label, - clusterResources: cluster.clusterResources.toString(), - server: cluster.cluster.server, - config: JSON.stringify(convertConfig(cluster)), - } - await vault.write(clusterData, `clusters/cluster-${cluster.label}/argocd-cluster-secret`) return { status: { result: 'OK', @@ -40,7 +32,6 @@ export const deleteCluster: StepCall = async (payload) => { try { const secretName = payload.args.secretName await deleteClusterSecret(secretName) - await payload.apis.vault.destroy(`clusters/cluster-${payload.args.label}/argocd-cluster-secret`) return { status: { result: 'OK', diff --git a/plugins/argocd/src/functions.ts b/plugins/argocd/src/functions.ts index 35682ed2f..17c564638 100644 --- a/plugins/argocd/src/functions.ts +++ b/plugins/argocd/src/functions.ts @@ -220,7 +220,7 @@ async function ensureInfraEnvValues(project: Project, environment: Environment, const cluster = getCluster(project, environment) const infraProject = await gitlabApi.getProjectById(repoId) const valueFilePath = getValueFilePath(project, cluster, environment) - const vaultCredentials = await vaultApi.Project.getCredentials() + const vaultCredentials = await vaultApi.getCredentials() const repositories: ArgoRepoSource[] = await Promise.all([ getArgoRepoSource('infra-apps', environment.name, gitlabApi), ...sourceRepos.map(repo => getArgoRepoSource(repo.internalRepoName, environment.name, gitlabApi)), diff --git a/plugins/argocd/src/index.ts b/plugins/argocd/src/index.ts index 1def78a5d..09840987b 100644 --- a/plugins/argocd/src/index.ts +++ b/plugins/argocd/src/index.ts @@ -4,7 +4,6 @@ import monitor from './monitor.js' import { deleteProject, upsertProject } from './functions.js' import { fixLabels } from './label-fix.js' import { deleteCluster, upsertCluster } from './cluster.js' -import { upsertZone } from './zone.js' export const plugin: Plugin = { infos, @@ -29,11 +28,6 @@ export const plugin: Plugin = { main: deleteCluster, }, }, - upsertZone: { - steps: { - main: upsertZone, - }, - }, }, monitor, start: fixLabels, diff --git a/plugins/argocd/src/zone.ts b/plugins/argocd/src/zone.ts deleted file mode 100644 index 4329f1352..000000000 --- a/plugins/argocd/src/zone.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { type StepCall, type ZoneObject, parseError } from '@cpn-console/hooks' -import { dump } from 'js-yaml' - -export const upsertZone: StepCall = async (payload) => { - try { - const zone = payload.args - const { gitlab, vault } = payload.apis - const values = { - vault: await vault.getCredentials(), - clusters: zone.clusterNames, - } - const zoneRepo = await gitlab.getOrCreateInfraProject(zone.slug) - await gitlab.commitCreateOrUpdate(zoneRepo.id, dump(values), 'argocd-values.yaml') - return { - status: { - result: 'OK', - message: 'Zone argocd configuration created/updated', - }, - } - } catch (error) { - return { - error: parseError(error), - status: { - result: 'KO', - message: 'Failed create/update zone argocd configuration', - }, - } - } -} diff --git a/plugins/gitlab/src/index.ts b/plugins/gitlab/src/index.ts index 11b685de9..7dc8d0d6f 100644 --- a/plugins/gitlab/src/index.ts +++ b/plugins/gitlab/src/index.ts @@ -52,7 +52,7 @@ export const plugin: Plugin = { upsertZone: { api: () => new GitlabZoneApi(), steps: { - pre: upsertZone, + main: upsertZone, post: commitFiles, }, }, diff --git a/plugins/vault/src/class.ts b/plugins/vault/src/class.ts index 687736b33..d16a9e380 100644 --- a/plugins/vault/src/class.ts +++ b/plugins/vault/src/class.ts @@ -37,16 +37,6 @@ export class VaultApi extends PluginApi { return this.token } - protected async destroy(path: string, kvName: string) { - if (path.startsWith('/')) - path = path.slice(1) - return await this.axios({ - method: 'delete', - url: `/v1/${kvName}/metadata/${path}`, - headers: { 'X-Vault-Token': await this.getToken() }, - }) - } - Kv = { upsert: async (kvName: string) => { const token = await this.getToken() @@ -142,6 +132,7 @@ export class VaultApi extends PluginApi { headers: { 'X-Vault-Token': await this.getToken() }, }) }, + delete: async (roleName: string) => { await this.axios.delete( `/v1/auth/approle/role/${roleName}`, @@ -150,25 +141,6 @@ export class VaultApi extends PluginApi { }, ) }, - getCredentials: async (roleName: string) => { - const { data: dataRole } = await this.axios.get( - `/v1/auth/approle/role/${roleName}/role-id`, - { - headers: { 'X-Vault-Token': await this.getToken() }, - }, - ) - const { data: dataSecret } = await this.axios.put( - `/v1/auth/approle/role/${roleName}/secret-id`, - 'null', // Force empty data - { - headers: { 'X-Vault-Token': await this.getToken() }, - }, - ) - return { - roleId: dataRole.data?.role_id, - secretId: dataSecret.data?.secret_id, - } - }, } } @@ -261,7 +233,35 @@ export class VaultProjectApi extends VaultApi { public async destroy(path: string = '/') { if (path.startsWith('/')) path = path.slice(1) - return super.destroy(`${this.projectRootDir}/${this.basePath}/${path}`, this.coreKvName) + return this.axios({ + method: 'delete', + url: `/v1/${this.coreKvName}/metadata/${this.projectRootDir}/${this.basePath}/${path}`, + headers: { 'X-Vault-Token': await this.getToken() }, + + }) + } + + public async getCredentials(): Promise { + const appRoleEnabled = await isAppRoleEnabled(this.axios, await this.getToken()) + if (!appRoleEnabled) return this.defaultAppRoleCredentials + const { data: dataRole } = await this.axios.get( + `/v1/auth/approle/role/${this.roleName}/role-id`, + { + headers: { 'X-Vault-Token': await this.getToken() }, + }, + ) + const { data: dataSecret } = await this.axios.put( + `/v1/auth/approle/role/${this.roleName}/secret-id`, + 'null', // Force empty data + { + headers: { 'X-Vault-Token': await this.getToken() }, + }, + ) + return { + ...this.defaultAppRoleCredentials, + roleId: dataRole.data?.role_id, + secretId: dataSecret.data?.secret_id, + } } Project = { @@ -285,15 +285,6 @@ export class VaultProjectApi extends VaultApi { await this.Group.delete() await this.Role.delete(this.roleName) }, - getCredentials: async () => { - const appRoleEnabled = await isAppRoleEnabled(this.axios, await this.getToken()) - if (!appRoleEnabled) return this.defaultAppRoleCredentials - const creds = await this.Role.getCredentials(this.roleName) - return { - ...this.defaultAppRoleCredentials, - ...creds, - } - }, } Group = { @@ -379,26 +370,4 @@ export class VaultZoneApi extends VaultApi { ) return await response.data } - - public async destroy(path: string = '/') { - if (path.startsWith('/')) - path = path.slice(1) - return super.destroy(path, this.kvName) - } - - public async getCredentials() { - const appRoleEnabled = await isAppRoleEnabled(this.axios, await this.getToken()) - if (!appRoleEnabled) { - return { - url: getConfig().publicUrl, - kvName: this.kvName, - } - } - const creds = await this.Role.getCredentials(this.roleName) - return { - url: getConfig().publicUrl, - kvName: this.kvName, - ...creds, - } - } } diff --git a/plugins/vault/src/functions.ts b/plugins/vault/src/functions.ts index 8c8a02084..0c0bfcb04 100644 --- a/plugins/vault/src/functions.ts +++ b/plugins/vault/src/functions.ts @@ -30,7 +30,7 @@ export const deployAuth: StepCall = async (payload) => { if (!payload.apis.vault) { throw new Error('no Vault available') } - const appRoleCreds = await payload.apis.vault.Project.getCredentials() + const appRoleCreds = await payload.apis.vault.getCredentials() if (getConfig().disableVaultSecrets) { return okStatus } diff --git a/plugins/vault/src/index.ts b/plugins/vault/src/index.ts index 017ecf14d..63caca760 100644 --- a/plugins/vault/src/index.ts +++ b/plugins/vault/src/index.ts @@ -1,4 +1,4 @@ -import type { ClusterObject, DefaultArgs, Plugin, Project, ProjectLite, ZoneObject } from '@cpn-console/hooks' +import type { DefaultArgs, Plugin, Project, ProjectLite, ZoneObject } from '@cpn-console/hooks' import { archiveDsoProject, deleteZone, deployAuth, getSecrets, upsertProject, upsertZone } from './functions.js' import infos from './infos.js' import monitor from './monitor.js' @@ -38,12 +38,6 @@ export const plugin: Plugin = { main: deleteZone, }, }, - upsertCluster: { - api: (c: ClusterObject) => new VaultZoneApi(c.zone.slug), - }, - deleteCluster: { - api: (c: ClusterObject) => new VaultZoneApi(c.zone.slug), - }, }, monitor, } @@ -52,7 +46,7 @@ declare module '@cpn-console/hooks' { interface HookPayloadApis { vault: Args extends (ProjectLite | Project) ? VaultProjectApi - : Args extends (ZoneObject | ClusterObject) + : Args extends (ZoneObject) ? VaultZoneApi : never }