import SharedConfig from '../shared/config/SharedConfig'; import SonarRoute from '../shared/types/Sonar/SonarRoute'; import axios, { AxiosInstance } from 'axios'; import Config from '../config/Config'; import SonarProjectCreation from '../shared/types/Sonar/SonarProjectCreation'; import https from 'https'; import GlobalHelper from '../helpers/GlobalHelper'; import DojoStatusCode from '../shared/types/Dojo/DojoStatusCode'; import express from 'express'; import GitlabRepository from '../shared/types/Gitlab/GitlabRepository'; class SonarManager { private instance: AxiosInstance = axios.create({ httpsAgent: new https.Agent({ rejectUnauthorized: false }) }); private getApiUrl(route: SonarRoute): string { return `${ SharedConfig.sonar.url }${ route }`; } /** * Assign a Gitlab Personal Access Token to a Sonar account (needed for any other request linked to gitlab) * @private */ private async setPAT() { const formData = new FormData(); formData.append('almSetting', 'dojo'); formData.append('pat', Config.gitlab.account.token); await this.instance.post(this.getApiUrl(SonarRoute.SET_PAT), formData, { headers: { Authorization: `Basic ${ btoa(SharedConfig.sonar.token + ":") }` } }); } private async executePostRequest<T>(url: string, data?: FormData) { await this.setPAT(); // Always set PAT to be sure it has been set return (await this.instance.post<T>(url, data, { headers: { Authorization: `Basic ${ btoa(SharedConfig.sonar.token + ":") }` } })).data; } private async executeGetRequest<T>(url: string) { return (await this.instance.get<T>(url, { headers: { Authorization: `Basic ${ btoa(SharedConfig.sonar.token + ":") }` } })).data; } async createProjectFromGitlab(projectId: number) { const formData = new FormData(); formData.append('almSetting', 'dojo'); formData.append('gitlabProjectId', projectId.toString()); return await this.executePostRequest<SonarProjectCreation>(this.getApiUrl(SonarRoute.PROJECT_CREATE_GITLAB), formData) } async addQualityGate(projectKey: string, qualityGate: string) { const formData = new FormData(); formData.append('projectKey', projectKey); formData.append('gateName', qualityGate); return await this.executePostRequest<undefined>(this.getApiUrl(SonarRoute.PROJECT_ADD_GATE), formData); } async addQualityProfile(projectKey: string, qualityProfile: string, language: string) { const formData = new FormData(); formData.append('project', projectKey); formData.append('qualityProfile', qualityProfile); formData.append('language', language); return await this.executePostRequest<unknown>(this.getApiUrl(SonarRoute.PROJECT_ADD_PROFILE), formData); } async createProjectWithQualities(gitlabRepository: GitlabRepository, qualityGate: string | null, qualityProfiles: string[] | null, req: express.Request, res: express.Response) { let sonarProject: SonarProjectCreation | undefined = undefined; try { sonarProject = await this.createProjectFromGitlab(gitlabRepository.id); if (sonarProject == undefined) { return await GlobalHelper.repositoryCreationError('Sonar error', undefined, req, res, DojoStatusCode.ASSIGNMENT_CREATION_SONAR_ERROR, DojoStatusCode.ASSIGNMENT_CREATION_SONAR_ERROR, gitlabRepository); } } catch ( error ) { return await GlobalHelper.repositoryCreationError('Sonar project creation error', error, req, res, DojoStatusCode.ASSIGNMENT_CREATION_SONAR_ERROR, DojoStatusCode.ASSIGNMENT_CREATION_INTERNAL_ERROR, gitlabRepository); } // Add gate and profiles to sonar project if ( qualityGate != undefined && qualityGate != "" ) { try { await this.addQualityGate(sonarProject.project.key, qualityGate); } catch ( error ) { return await GlobalHelper.repositoryCreationError('Sonar gate error', error, req, res, DojoStatusCode.ASSIGNMENT_SONAR_GATE_NOT_FOUND, DojoStatusCode.ASSIGNMENT_SONAR_GATE_NOT_FOUND, gitlabRepository); } } if ( qualityProfiles != undefined && qualityProfiles.length > 0 ) { for ( const profile of qualityProfiles ) { try { const [ lang, name ] = profile.split('/'); if (lang.trim() != '' && name.trim() != '') { await this.addQualityProfile(sonarProject.project.key, name.trim(), lang.trim()); } else { return await GlobalHelper.repositoryCreationError('Sonar profile invalid', undefined, req, res, DojoStatusCode.ASSIGNMENT_SONAR_PROFILE_NOT_FOUND, DojoStatusCode.ASSIGNMENT_SONAR_PROFILE_NOT_FOUND, gitlabRepository); } } catch ( error ) { return await GlobalHelper.repositoryCreationError('Sonar profile not found', error, req, res, DojoStatusCode.ASSIGNMENT_SONAR_PROFILE_NOT_FOUND, DojoStatusCode.ASSIGNMENT_SONAR_PROFILE_NOT_FOUND, gitlabRepository); } } } return sonarProject; } async getLanguages() { const resp = await this.executeGetRequest<{ languages: { key: string, name: string }[]}>(this.getApiUrl(SonarRoute.GET_LANGUAGES)) return resp.languages.map(l => l.key) } } export default new SonarManager();