Guassp — Синхронізатор доступу користувачів GitLab для проектів SonarQube
Проект призначений для створення розрахованої на багато користувачів інтеграції SonarQube та GitLab. Бачимість проекту та дозволи користувачів будуть встановлені в SonarQube таким же чином, як дозволи для проекту в GitLab.
- Реалізація
- Вимоги
- Компоненти
- Зображення контейнерів
- Швидкий старт
- Конфігурація
- API
- Пайплайн
- Метрики
- Складання та налагодження проекту
Цей застосунок складається з API інтерфейсу, який приймає запити на
оновлення дозволів з конвеєра GitLab CI, де вся довіра побудована
навколо CI_JOB_TOKEN
, довірені завдання додаються до черги
завдань RQ (Redis Queue). Завдання обробляються бекенд-воркерами Worker,
а для виведення статистики використовується окремий експортер метрик
prometheus.
Права доступу видаються за рівнем доступу ролей SonarQube відповідно до
наявних дозволів користувачів проекту в GitLab.
Враховується те, як GitLab реалізує права доступу користувачів у
проекті, та користувачів із запрошених груп, де рівні доступу імітуються
відповідно до GitLab.
- SonarQube повинен мати налаштовану ALM інтеграцію з вашим GitLab, а ім'я
ключа інтеграції ви повинні вказати в
SONARQUBE_ALM_KEY
; - Аутентифікація в SonarQube повинна відбуватися тільки через ALM GitLab, інакше пошук користувачів буде порушено, права синхронізуються тільки для явно відповідного облікового запису, що прийшов з GitLab;
- Ви повинні мати можливість надати токен доступу з адміністративними привілеями
для SonarQube в
SONARQUBE_TOKEN
для коректної роботи worker; - Ви повинні створити службового користувача в GitLab, який повинен мати доступ
з правами не нижче developer у всіх проектах, які ви хочете аналізувати в
SonarQube, цим користувачем ви повинні увійти в SonarQube і дати йому
глобальні права на виконання аналізу та створення проектів. Після чого ви
можете використовувати токен цього користувача:
- Токен користувача отриманий в SonarQube як
SONARQUBE_TOKEN
, що використовується в CI пайплайні для виконання аналізу та управління проектом. - Токен користувача отриманий у GitLab як
GITLAB_TOKEN
для worker, потрібен для отримання списку всіх учасників групи або проекту, включаючи успадкованих та запрошених учасників
- Токен користувача отриманий в SonarQube як
- Ім'я проекту, що реєструється в SonarQube, має бути рівним
$CI_PROJECT_NAMESPACE/$CI_PROJECT_NAME
а ключ проекту рекомендується встановити вgitlab:$CI_PROJECT_ID
. Тільки при таких налаштуваннях синхронізація буде проходити успішно, інші стани можливі, але не перевірялися.
- Найкращий досвід буде отримано при використанні плагіна sonarqube-community-branch-plugin, що додає підтримку аналізу гілок та PR для ваших проектів. Також тут вам знадобиться раніше створений системний користувач GitLab з правами developer, який дозволить вам декорувати MR у ваших проектах.
- Для прозорої інтеграції найкраще використовувати наведений приклад скрипта sq-integration-taks для пайплайну GitLab CI, інакше інші параметри реєстрації проекту можуть працювати не коректно або зовсім порушити роботу. Приклад також заточений під наявність плагіну sonarqube-community-branch-plugin та виконання OWASP DependencyCheck
- Використовуйте метрики Prometheus та Grafana для аналізу роботи синхронізатора.
Проект реалізований на flask, для WSGI застосований bjoern, робота з API GitLab відбувається через python-gitlab, а SonarQube API через python-sonarqube-api. Для обробки черги повідомлень використовується RQ, чиї метрики віддає rq-exporter.
Ви можете отримати зображення з регістрів:
ghcr.io/woozymasta/guassp:latest
quay.io/woozymasta/guassp:latest
docker.io/woozymasta/guassp:latest
Для швидкого старту можна використати приклад із docker-compose:
- docker-compose.env - змініть налаштування у файлі налаштувань оточення
- docker-compose.yml - виконайте
docker-compose up -d
Щоб запустити потрібну утиліту, передайте в контейнер або сценарій
guassp.sh
аргумент:
worker
(за замовчуванням) - процесор завдань для черги;api
- API для контролю завдань;exporter
- prometheus метрики;all-in-one
- запускworker
,api
таexporter
одразу;API -DEV
- запуск API через сервер Flask Dev.
LISTEN_ADDRESS
=0.0.0.0
- Хост для публікації API;LISTEN_PORT
=5000
- Порт для публікації API;LOG_LEVEL
=INFO
- Рівень логування;SECRET_KEY
=secret
- Секретний ключ;QUEUE_RESULT_TTL
=7200
- Час зберігання результатів черги;MORE_ACCURATE_SYNC
=true
- Пошук користувачів у SonarQube електронною поштою GitLab, інакше пошук відбувається на ім'я користувача. Це викликає ще один запит API для кожного користувача, це більш точно, але повільніше вдвічі.
GITLAB_URL
=https://gitlab.com
- Адреса сервера GitLab;GITLAB_TOKEN
- Токен доступу до GitLab, повинен мати права на перегляд учасників та їх прав доступу для проектів, що обслуговуються;GITLAB_SKIP_USERS
- Список (розділених комою) ID користувачів, які будуть пропущені при синхронізації.
SONARQUBE_URL
- Адреса сервера SonarQube;SONARQUBE_TOKEN
- Токен доступу до SonarQube з адміністративними привілеями;SONARQUBE_ALM_KEY
- Ключ ALM (назва) інтеграції з GitLab;SONARQUBE_SKIP_GROUPS
- Список (розділених комою) груп, які будуть проігноровані при синхронізації.
REDIS_URL
=redis://localhost:6379/0
- URL-адреса підключення до сервера Redis.
EXPORTER_LISTEN_ADDRESS
=0.0.0.0
- Хост для публікації Prometeus метрик;EXPORTER_LISTEN_PORT
=9726
- Порт для публікації Prometeus метрик.
POST
/task
{"job_token": str}Headers:
JOB-TOKEN
orAuthorization: Bearer
Потрібно передати токен завдання у будь-якому з варіантів:
curl -sL http://127.0.0.1:5000/task \
-H "Content-Type: application/json" \
-d '{"job_token": "'$CI_JOB_TOKEN'"}' | jq
curl -sL http://127.0.0.1:5000/task -X POST \
-H "JOB-TOKEN: $CI_JOB_TOKEN" | jq
curl -sL http://127.0.0.1:5000/task -X POST \
-H "Authorization: Bearer $CI_JOB_TOKEN" | jq
Токен завдання може бути переданий заголовком JOB-TOKEN
або
Authorization: Bearer
або бути значенням ключа job_token
у JSON
GET
/tasks
curl -sL http://127.0.0.1:5000/tasks | jq
curl -sL http://127.0.0.1:5000/tasks | jq -er '.tasks | keys'
GET
/task/<uuid:job_uuid>
curl -sL http://127.0.0.1:5000/task/8b155172-cfcf-4777-b9f4-bfce53b6eb0e | jq
DELETE
/task/<uuid:job_uuid>
curl -sL http://127.0.0.1:5000/task/8b155172-cfcf-4777-b9f4-bfce53b6eb0e \
-X DELETE | jq
POST
/task_manual/<int:prj_id>
curl -sL http://127.0.0.1:5000/task_manual/111 \
-X POST | jq
GET
/health
Здоров'я API, доступність самого додатку і черги завданнь.
У пайплайні GitLab CI в першу чергу потрібно переконатися, що налаштування ALM зроблено та відноситься до вашого проекту, після чого можна надсилати завдання на синхронізацію в guassp. Ось тепер можна розпочинати аналіз проекту.
Для публікації API Guassp за Nginx як частини API SonarQube, дивіться до прикладу конфігурації Nginx
: "${SONARQUBE_PROJECT_KEY:=gitlab:$CI_PROJECT_ID}"
curl --location --fail --user "$SONARQUBE_TOKEN:" \
"$SONARQUBE_URL/api/alm_settings/set_gitlab_binding" \
-d "almSetting=$SONARQUBE_ALM_NAME" \
-d "project=$SONARQUBE_PROJECT_KEY" \
-d "repository=$CI_PROJECT_ID"
curl --location --fail -X POST -H "JOB-TOKEN: $CI_JOB_TOKEN" \
"$SONARQUBE_URL/api/guassp/task"
Більш об'ємний приклад скрипту виконання SonarQube у пайплайні ви можете
побачити у файлі
sq-integration-taks.sh
Метрики реалізовані за допомогою проекту rq-exporter
Dashboard ID 12196
підходить для візуалізації в Grafana або використовуйте
його адаптацію, який виводитиме лише метрики з guassp.
Набір команд для швидкого локального налагодження
# Build
podman build -t guassp .
# Redis
podman run --rm -d -p 6379:6379 --name redis redis
# API
podman run --rm -d -p 5000:5000 --env-file .env --name guassp-api localhost/guassp:latest api
# Workers
podman run --rm -d --env-file .env --name guassp-worker-1 localhost/guassp:latest worker
podman run --rm -d --env-file .env --name guassp-worker-2 localhost/guassp:latest worker
# Exporter
podman run --rm -d -p 9726:9726 --env-file .env --name guassp-exporter localhost/guassp:latest exporter
# Check
curl 0.0.0.0:9726 -s | grep -v '^#'
curl 0.0.0.0:5000/tasks -s | jq
curl 0.0.0.0:5000/task -s -X POST -H "JOB-TOKEN: $CI_JOB_TOKEN" | jq
Або запустимо локально, для цього потрібно встановити залежності
apt-get install -y libev-dev libevdev2
python -m venv .venv
./.venv/bin/activate
pip install requirements.txt
Або для простоти запустити застосунки через скрипт guassp
./guassp.sh api
./guassp.sh worker
./guassp.sh exporter