Skip to content

Commit

Permalink
Merge pull request #429 from dnum-mi/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
this-is-tobi committed May 22, 2023
2 parents 58be548 + 2e84326 commit dc26737
Show file tree
Hide file tree
Showing 24 changed files with 153 additions and 78 deletions.
58 changes: 58 additions & 0 deletions .gitlab-ci-dso.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# This file is an example on how to use CI on Gitlab DSO platform, it is not yet functionnal with environnment
# references for includes are at https://github.com/hexa-forge/gitlab-ci-catalog
stages:
- read-secret
- build-push

include:
- project: $CATALOG_PATH
file: vault-ci.yml
ref: main
- project: $CATALOG_PATH
file: kaniko-ci.yml
ref: main

vault:read_secret:
stage: read-secret

.build-push-branches:
only:
refs:
- branches
extends: .kaniko:build-push
stage: build-push
variables:
WORKING_DIR: .

.build-push-tags:
only:
refs:
- tags
extends: .kaniko:build-push
stage: build-push
variables:
WORKING_DIR: .

build-push-server-tag:
extends: .build-push-tags
variables:
IMAGES_NAMES: server:$CI_COMMIT_TAG server:latest
DOCKERFILE: apps/server/Dockerfile

build-push-client-tag:
extends: .build-push-tags
variables:
IMAGES_NAMES: client:$CI_COMMIT_TAG client:latest
DOCKERFILE: apps/client/Dockerfile

build-push-server-branch:
extends: .build-push-branches
variables:
IMAGES_NAMES: server:$CI_COMMIT_BRANCH
DOCKERFILE: apps/server/Dockerfile

build-push-client-branch:
extends: .build-push-branches
variables:
IMAGES_NAMES: client:$CI_COMMIT_BRANCH
DOCKERFILE: apps/client/Dockerfile
1 change: 1 addition & 0 deletions apps/server/env/.env-example
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

SERVER_PORT=4000
SESSION_SECRET=a-very-strong-secret-with-more-than-32-char
PROJECTS_ROOT_DIR=forge-mi/projects

# Database in /env/.env

Expand Down
1 change: 1 addition & 0 deletions apps/server/env/.env.ci-example
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

SERVER_PORT=4000
SESSION_SECRET=a-very-strong-secret-with-more-than-32-char
PROJECTS_ROOT_DIR=forge-mi/projects

# Database in /env/.env.ci

Expand Down
1 change: 1 addition & 0 deletions apps/server/env/.env.int-example
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# App
SERVER_PORT=4000
SESSION_SECRET=a-very-strong-secret-with-more-than-32-char
PROJECTS_ROOT_DIR=forge-mi/projects

# Database in /env/.env.int

Expand Down
18 changes: 9 additions & 9 deletions apps/server/src/controllers/environment.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import hooksFns from '../plugins/index.js'
import { addLogs } from '../models/queries/log-queries.js'
import { getOrganizationById } from '../models/queries/organization-queries.js'
import { getInfraProjectRepositories } from '../models/queries/repository-queries.js'
import { gitlabUrl, harborUrl, projectPath } from '../utils/env.js'
import { gitlabUrl, harborUrl, projectRootDir } from '../utils/env.js'

// GET
export const getEnvironmentByIdController = async (req, res) => {
Expand Down Expand Up @@ -66,7 +66,7 @@ export const initializeEnvironmentController = async (req, res) => {
let env
let project
let organization
let ownerId
let owner
try {
project = await getProjectById(projectId)
organization = await getOrganizationById(project.organization)
Expand All @@ -82,7 +82,7 @@ export const initializeEnvironmentController = async (req, res) => {

env = await initializeEnvironment(data)
await lockProject(projectId)
ownerId = await getSingleOwnerByProjectId(projectId)
owner = await getSingleOwnerByProjectId(projectId)

req.log.info({
...getLogInfos({
Expand All @@ -108,7 +108,7 @@ export const initializeEnvironmentController = async (req, res) => {
const environmentName = env.dataValues.name
const projectName = project.dataValues.name
const organizationName = organization.name
const gitlabBaseURL = `${gitlabUrl}/${projectPath.join('/')}/${organizationName}/${projectName}/`
const gitlabBaseURL = `${gitlabUrl}/${projectRootDir}/${organizationName}/${projectName}/`
const repositories = (await getInfraProjectRepositories(project.id)).map(({ internalRepoName }) => ({
url: `${gitlabBaseURL}/${internalRepoName}.git`,
internalRepoName,
Expand All @@ -120,7 +120,7 @@ export const initializeEnvironmentController = async (req, res) => {
organization: organizationName,
repositories,
registryHost,
ownerId,
owner,
}
const results = await hooksFns.initializeEnvironment(envData)
await addLogs('Create Environment', results, userId)
Expand All @@ -141,10 +141,10 @@ export const initializeEnvironmentController = async (req, res) => {
try {
if (isServicesCallOk) {
await updateEnvironmentCreated(env.id)
const ownerId = await getSingleOwnerByProjectId(projectId)
if (ownerId !== userId) {
const owner = await getSingleOwnerByProjectId(projectId)
if (owner.id !== userId) {
await setPermission({
userId: ownerId,
userId: owner.id,
environmentId: env.id,
level: 2,
})
Expand Down Expand Up @@ -215,7 +215,7 @@ export const deleteEnvironmentController = async (req, res) => {
const environmentName = env.name
const projectName = project.name
const organizationName = organization.name
const gitlabBaseURL = `${gitlabUrl}/${projectPath.join('/')}/${organizationName}/${projectName}/`
const gitlabBaseURL = `${gitlabUrl}/${projectRootDir}/${organizationName}/${projectName}/`
const repositories = (await getInfraProjectRepositories(project.id)).map(({ internalRepoName }) => ({
url: `${gitlabBaseURL}/${internalRepoName}.git`,
internalRepoName,
Expand Down
8 changes: 4 additions & 4 deletions apps/server/src/controllers/permission.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,8 @@ export const updatePermissionController = async (req, res) => {
const requestorPermission = await getPermissionByUserIdAndEnvironmentId(userId, environmentId)
if (!requestorPermission) throw new Error('Le requérant doit avoir des droits sur l\'environnement pour modifier des permissions')

const ownerId = await getSingleOwnerByProjectId(projectId)
if (data.userId === ownerId) throw new Error('La permission du owner du projet ne peut être modifiée')
const owner = await getSingleOwnerByProjectId(projectId)
if (data.userId === owner.id) throw new Error('La permission du owner du projet ne peut être modifiée')

const permission = await updatePermission({ userId: data.userId, environmentId, level: data.level })
req.log.info({
Expand Down Expand Up @@ -123,8 +123,8 @@ export const deletePermissionController = async (req, res) => {
const requestorPermission = await getPermissionByUserIdAndEnvironmentId(requestorId, environmentId)
if (!requestorPermission) throw new Error('Le requérant doit avoir des droits sur l\'environnement pour supprimer des permissions')

const ownerId = await getSingleOwnerByProjectId(projectId)
if (userId === ownerId) throw new Error('La permission du owner du projet ne peut être supprimée')
const owner = await getSingleOwnerByProjectId(projectId)
if (userId === owner.id) throw new Error('La permission du owner du projet ne peut être supprimée')

const permission = await deletePermission(userId, environmentId)

Expand Down
19 changes: 8 additions & 11 deletions apps/server/src/controllers/project.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
updateProjectServices,
updateProject,
} from '../models/queries/project-queries.js'
import { getOrCreateUser, getUserById } from '../models/queries/user-queries.js'
import { getOrCreateUser } from '../models/queries/user-queries.js'
import {
deleteRoleByUserIdAndProjectId,
getRoleByUserIdAndProjectId,
Expand Down Expand Up @@ -43,7 +43,7 @@ import { calcProjectNameMaxLength } from 'shared/src/utils/functions.js'
import { getServices } from '../utils/services.js'
import { addLogs } from '../models/queries/log-queries.js'
import hooksFns from '../plugins/index.js'
import { gitlabUrl, projectPath } from '../utils/env.js'
import { gitlabUrl, projectRootDir } from '../utils/env.js'

// GET
export const getUserProjectsController = async (req, res) => {
Expand Down Expand Up @@ -112,9 +112,7 @@ export const getProjectOwnerController = async (req, res) => {
const role = await getRoleByUserIdAndProjectId(userId, projectId)
if (!role) throw new Error('Vous n\'êtes pas membre du projet')

const ownerId = await getSingleOwnerByProjectId(projectId)
const owner = await getUserById(ownerId)

const owner = await getSingleOwnerByProjectId(projectId)
req.log.info({
...getLogInfos({ owner }),
description: 'Propriétaire du projet récupéré avec succès',
Expand Down Expand Up @@ -142,7 +140,9 @@ export const createProjectController = async (req, res) => {
let organization

try {
const isValid = await hooksFns.createProject({ email: user.email }, true)
owner = await getOrCreateUser({ id: user.id, email: user?.email, firstName: user?.firstName, lastName: user?.lastName })

const isValid = await hooksFns.createProject({ owner }, true)

if (isValid?.failed) {
const reasons = Object.values(isValid)
Expand All @@ -154,7 +154,6 @@ export const createProjectController = async (req, res) => {
addLogs('Create Project Validation', { reasons }, user.id)
return
}
owner = await getOrCreateUser({ id: user.id, email: user?.email, firstName: user?.firstName, lastName: user?.lastName })

organization = await getOrganizationById(data.organization)

Expand Down Expand Up @@ -194,9 +193,7 @@ export const createProjectController = async (req, res) => {
const projectData = {
...project,
organization: organization.name,
email: owner.email,
userInfos: { firstName: owner.firstName, lastName: owner.lastName },
userId: owner.id,
owner,
}
projectData.project = projectData.name
delete projectData.name
Expand Down Expand Up @@ -358,7 +355,7 @@ export const archiveProjectController = async (req, res) => {
const environmentsName = environments.map(env => env.name)
const projectName = project.name
const organizationName = organization.name
const gitlabBaseURL = `${gitlabUrl}/${projectPath.join('/')}/${organization.name}/${project.name}/`
const gitlabBaseURL = `${gitlabUrl}/${projectRootDir}/${organization.name}/${project.name}/`
const repositories = (await getInfraProjectRepositories(project.id)).map(({ internalRepoName }) => ({
url: `${gitlabBaseURL}/${internalRepoName}.git`,
internalRepoName,
Expand Down
6 changes: 3 additions & 3 deletions apps/server/src/controllers/repository.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import { getLogInfos } from '../utils/logger.js'
import { sendOk, sendCreated, sendUnprocessableContent, sendNotFound, sendBadRequest, sendForbidden } from '../utils/response.js'
import { getOrganizationById } from '../models/queries/organization-queries.js'
import { addLogs } from '../models/queries/log-queries.js'
import { gitlabUrl, projectPath } from '../utils/env.js'
import { gitlabUrl, projectRootDir } from '../utils/env.js'
import hooksFns from '../plugins/index.js'

// GET
Expand Down Expand Up @@ -90,7 +90,7 @@ export const createRepositoryController = async (req, res) => {
let project
let repo
try {
const isValid = await hooksFns.createProject({ email: user.email }, true)
const isValid = await hooksFns.createProject({ user }, true)

if (isValid?.failed) {
const reasons = Object.values(isValid)
Expand Down Expand Up @@ -145,7 +145,7 @@ export const createRepositoryController = async (req, res) => {
organization: organization.name,
services: project.services,
environment: environmentNames,
internalUrl: `${gitlabUrl}/${projectPath.join('/')}/${organization.name}/${project.name}/${repo.dataValues.internalRepoName}.git`,
internalUrl: `${gitlabUrl}/${projectRootDir}/${organization.name}/${project.name}/${repo.dataValues.internalRepoName}.git`,
}
if (data.isPrivate) {
repoData.externalUserName = data.externalUserName
Expand Down
10 changes: 9 additions & 1 deletion apps/server/src/models/queries/users-projects-queries.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { sequelize } from '../../connect.js'
import { getUserModel } from '../user.js'
import { getUsersProjectsModel } from '../users-projects.js'

// SELECT
Expand Down Expand Up @@ -27,7 +28,14 @@ export const getSingleOwnerByProjectId = async (ProjectId) => {
},
limit: 1,
})
return Array.isArray(res) ? res[0].UserId : res.UserId
const user = Array.isArray(res)
? res[0]
: res
const userId = user.dataValues ? user.dataValues.UserId : user.UserId
const resUser = await getUserModel().findByPk(userId, {
raw: true,
})
return resUser
}

// UPDATE
Expand Down
29 changes: 8 additions & 21 deletions apps/server/src/plugins/core/gitlab/files/.gitlab-ci.yml
Original file line number Diff line number Diff line change
@@ -1,24 +1,11 @@
repo_pull_sync:
image: ubuntu:20.04
stage: build
include:
- project: $CATALOG_PATH
file: mirror.yml
ref: main

repo_pull_sync:
extends: .repo_pull_sync
only:
- api
- triggers
before_script:
- apt-get update -y && apt install gpg wget -y
- wget -O- https://apt.releases.hashicorp.com/gpg | gpg --dearmor | tee /usr/share/keyrings/hashicorp-archive-keyring.gpg >/dev/null
- echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com focal main" | tee /etc/apt/sources.list.d/hashicorp.list
- apt-get update -y && apt-get install openssh-client git vault -y
script:
- export VAULT_ADDR=$VAULT_SERVER_URL
- export VAULT_TOKEN="$(vault write -field=token auth/jwt/login role=default-ci jwt=$CI_JOB_JWT)"
- export GIT_INPUT_USER=`vault kv get -field=GIT_INPUT_USER forge-dso/${CI_PROJECT_NAMESPACE}/${CI_PROJECT_NAME}`
- export GIT_INPUT_PASSWORD=`vault kv get -field=GIT_INPUT_PASSWORD forge-dso/${CI_PROJECT_NAMESPACE}/${CI_PROJECT_NAME}`
- export GIT_INPUT_URL=`vault kv get -field=GIT_INPUT_URL forge-dso/${CI_PROJECT_NAMESPACE}/${CI_PROJECT_NAME}`
- export GIT_OUTPUT_USER=`vault kv get -field=GIT_OUTPUT_USER forge-dso/${CI_PROJECT_NAMESPACE}/${CI_PROJECT_NAME}`
- export GIT_OUTPUT_PASSWORD=`vault kv get -field=GIT_OUTPUT_PASSWORD forge-dso/${CI_PROJECT_NAMESPACE}/${CI_PROJECT_NAME}`
- export GIT_OUTPUT_URL=`vault kv get -field=GIT_OUTPUT_URL forge-dso/${CI_PROJECT_NAMESPACE}/${CI_PROJECT_NAME}`
- git clone "https://${GIT_INPUT_USER}:${GIT_INPUT_PASSWORD}@${GIT_INPUT_URL}" ./clonerepo
- cd clonerepo
- git checkout ${GIT_BRANCH_DEPLOY}
- git push --force --prune "https://${GIT_OUTPUT_USER}:${GIT_OUTPUT_PASSWORD}@${GIT_OUTPUT_URL}"
- web
8 changes: 4 additions & 4 deletions apps/server/src/plugins/core/gitlab/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import { createUser, getUser } from './user.js'

// Check
export const checkApi = async (payload) => {
const { email } = payload.args
const user = await getUser(email)
const { owner } = payload.args
const user = await getUser(owner.email)
if (user?.id === 1) {
return {
status: {
Expand All @@ -27,10 +27,10 @@ export const checkApi = async (payload) => {
// Project
export const createDsoProject = async (payload) => {
try {
const { project, organization, email } = payload.args
const { project, organization, owner } = payload.args

const group = await createGroup(project, organization)
const user = await createUser(email)
const user = await createUser(owner.email)
const groupMember = await addGroupMember(group.id, user.id, 40)

return {
Expand Down
8 changes: 4 additions & 4 deletions apps/server/src/plugins/core/gitlab/utils.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { Gitlab } from '@gitbeaker/node'
import { gitlabToken, gitlabUrl, projectPath } from '../../../utils/env.js'
import { gitlabToken, gitlabUrl, projectRootDir } from '../../../utils/env.js'

export const api = new Gitlab({ token: gitlabToken, host: gitlabUrl })

let groupRootId

export const getGroupRootId = async () => {
if (groupRootId) return groupRootId
const groupRootSearch = await api.Groups.search(projectPath.join('/'))
groupRootId = (groupRootSearch.find(grp => grp.full_path === projectPath.join('/'))).id
if (!groupRootId) throw Error(`Gitlab inaccessible, impossible de trouver le groupe ${projectPath}`)
const groupRootSearch = await api.Groups.search(projectRootDir)
groupRootId = (groupRootSearch.find(grp => grp.full_path === projectRootDir)).id
if (!groupRootId) throw Error(`Gitlab inaccessible, impossible de trouver le groupe ${projectRootDir}`)
return groupRootId
}
4 changes: 2 additions & 2 deletions apps/server/src/plugins/core/keycloak/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@ import { getkcClient } from './client.js'
export const createKeycloakProjectGroup = async (payload) => {
const kcClient = await getkcClient()
try {
const { organization, project, userId } = payload.args
const { organization, project, owner } = payload.args
const projectName = `${organization}-${project}`
let group = await getProjectGroupByName(kcClient, projectName)
if (!group) {
group = await kcClient.groups.create({
name: projectName,
})
}
await addMembers(kcClient, [userId], group.id)
await addMembers(kcClient, [owner.id], group.id)

return {
status: { result: 'OK' },
Expand Down
4 changes: 2 additions & 2 deletions apps/server/src/plugins/core/kubernetes/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ import { getNsObject, getSecretObject } from './utils.js'

export const createKubeNamespace = async (payload) => {
try {
const { organization, project, environment } = payload.args
const { organization, project, environment, owner } = payload.args
const nsName = `${organization}-${project}-${environment}`
const nsObject = getNsObject(organization, project, environment)
const nsObject = getNsObject(organization, project, environment, owner)
const nsSearch = (await k8sApi.listNamespace()).body
const ns = nsSearch.items.find(ns => ns.metadata.name === nsName)
if (!ns) {
Expand Down
Loading

0 comments on commit dc26737

Please sign in to comment.