Guassp — Синхронизатор доступа пользователей GitLab для проектов SonarQube
Проект предназначен для создания многопользовательской интеграции SonarQube и GitLab. Видимость проекта и разрешения пользователей будут установлены в SonarQube таким же образом, как разрешения для проекта в GitLab.
Эта утилита состоит из API интерфейса, который принимает запросы на
обновление разрешений из конвейера GitLab CI, где все доверие построено
вокруг CI_JOB_TOKEN, доверенные задачи добавляются в очередь
заданий RQ (Redis Queue). Задания обрабатываются бэкенд-воркерами Worker,
а для вывода статистики используется отдельный экспортер метрик prometheus.

Права доступа выдаются по уровню доступа ролей SonarQube в соответствии
с имеющимися разрешениями у пользователей проекта в GitLab.
Учитывается то, как GitLab реализует права доступа пользователей в
проекте, и пользователей из приглашенных групп, где уровни доступа
имитируются в соответствии с GitLab.


SONARQUBE_ALM_KEY;SONARQUBE_TOKEN для корректной работы worker;SONARQUBE_TOKEN используемый
в CI пайплайне для выполнения анализа и управления проектом.GITLAB_TOKEN для worker,
нужен для получения списка всех участников группы или проекта,
включая унаследованных и приглашенных участников$CI_PROJECT_NAMESPACE/$CI_PROJECT_NAME а ключ проекта рекомендуеться
установить в gitlab:$CI_PROJECT_ID. Только при таких настройках
синхронизация будет проходить успешно, другие состояния возможны но не
проверялись.Проект реализован на flask, для WSGI применен bjoern, работа с API GitLab происходит через python-gitlab, а SonarQube API через python-sonarqube-api. Для обработки очереди сообщений используется RQ чьи метрики отдает rq-exporter.
Вы можете получить образы из реестров:
ghcr.io/woozymasta/guassp:latestquay.io/woozymasta/guassp:latestdocker.io/woozymasta/guassp:latestДля быстрого старта можно использовать пример из docker-compose:
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 для каждого
пользователя, это более точно но медленнее в 2 раза.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-TOKENorAuthorization: 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