Skip to content

Latest commit

 

History

History
332 lines (252 loc) · 15.3 KB

README-ru.md

File metadata and controls

332 lines (252 loc) · 15.3 KB

Guassp - GitLab User Access Synchronizer for SonarQube Projects

GuasspСинхронизатор доступа пользователей GitLab для проектов SonarQube

Проект предназначен для создания многопользовательской интеграции SonarQube и GitLab. Видимость проекта и разрешения пользователей будут установлены в SonarQube таким же образом, как разрешения для проекта в GitLab.

Этот документ доступен на языках: eng 🇬🇧, ua 🇺🇦, rus 🇷🇺

Реализация

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

scheme

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

permissions
role-mapping

Требования

Обязательно

  • SonarQube должен иметь настроенную ALM интеграцию c вашим GitLab, а имя ключа интеграции вы должны указать в SONARQUBE_ALM_KEY;
  • Аутентификация в SonarQube должна происходить только через ALM GitLab, иначе поиск пользователей будет нарушен, права синхронизируются только для явно соответствующей учетной записи пришедшей из GitLab;
  • Вы должны иметь возможность предоставить токен доступа c административными привилегиями для SonarQube в SONARQUBE_TOKEN для корректной работы worker;
  • Вы должны создать служебного пользователя в GitLab, который должен иметь доступ с правами не ниже developer во всех проектах которые вы хотите анализировать в SonarQube, этим пользователем вы должны войти в SonarQube и дать ему глобальные права на выполнение анализа и создание проектов. После чего вы можете использовать токен этого пользователя:
    • Токен пользователя полученный в SonarQube как SONARQUBE_TOKEN используемый в CI пайплайне для выполнения анализа и управления проектом.
    • Токен пользователя полученный в GitLab как GITLAB_TOKEN для worker, нужен для получения списка всех участников группы или проекта, включая унаследованных и приглашенных участников
  • Имя регистрируемого в SonarQube проекта должно быть равно $CI_PROJECT_NAMESPACE/$CI_PROJECT_NAME а ключ проекта рекомендуеться установить в gitlab:$CI_PROJECT_ID. Только при таких настройках синхронизация будет проходить успешно, другие состояния возможны но не проверялись.

Рекомендуемо

  • Лучший опыт будет получен при использовании плагина sonarqube-community-branch-plugin добавляющего поддержку анализа веток и PR для ваших проектов. Также здесь вам пригодится ранее созданный системный пользователь в GitLab c правами 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.

Образы контейнеров

Вы можете получить образы из реестров:

Быстрый старт

Для быстрого старта можно использовать пример из docker-compose:

  1. docker-compose.env - изменитe настройки в файле настроек окружения
  2. 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 для каждого пользователя, это более точно но медленнее в 2 раза.

Параметры работы с GitLab

  • GITLAB_URL=https://gitlab.com - Адрес сервера GitLab;
  • GITLAB_TOKEN - Токен доступа к GitLab, должен иметь права на просмотр участников и их прав доступа для обслуживаемых проектов;
  • GITLAB_SKIP_USERS - Список (разделенных запятой) ID пользователей которые будут пропущены при синхронизации.

Параметры работы с SonarQube

  • SONARQUBE_URL - Адрес сервера SonarQube;
  • SONARQUBE_TOKEN - Токен доступа к SonarQube с административными привилегиями;
  • SONARQUBE_ALM_KEY - Ключ ALM (название) интеграции с GitLab;
  • SONARQUBE_SKIP_GROUPS - список (разделенных запятой) групп которые будут пропущены при синхронизации.

Параметры работы с Redis

  • REDIS_URL=redis://localhost:6379/0 - URL подключения к серверу Redis.

Параметры экспортера метрик Prometheus

  • EXPORTER_LISTEN_ADDRESS=0.0.0.0 - Хост для публикации Prometeus метрик;
  • EXPORTER_LISTEN_PORT=9726 - Порт для публикации Prometeus метрик.

API

Регистрация задания

POST /task

{"job_token": str}

Headers: JOB-TOKEN or Authorization: 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

Ручная регистрация задания c ID проекта GitLab

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