Перейти к содержанию

Подключение вебхуков

Codescoring поддерживает систему оповещений на базе вебхуков. При возникновении событий отправляется POST HTTP-запрос на указанный URL.

Добавление нового вебхука

Для добавления нового вебхука на инсталляции необходимо выполнить следующие действия:

  1. Перейти в раздел Settings -> Webhooks.
  2. Нажать на кнопку Setup new.
  3. Заполнить поля в форме:

    • Name – название в системе CodeScoring;
    • URL – адрес с указанием протокола. Например: http://webhook.com/;
    • Projects - список проектов, для которых будут применяться вебхуки. Если поле пустое, будут учитываться все проекты;
    • Events – список событий, на которые сработает оповещение;
    • Token – токен, который передается в HTTP-запросе (заголовок X-CodeScoring-Authentication);
  4. Проверить подключение после заполнения данных по кнопке Test it. При тестировании используется триггер test с пустым payload.

После создания нового подключения по кнопке Setup now вебхук отобразится в списке раздела, с возможностью просмотреть информацию о нем (View), изменить параметры вебхука (Edit), или удалить его (Delete).

Структура тела запроса

{
  "events": [
    {
      "created_at": "datetime_in_iso_format",
      "trigger": "trigger_name",
      "payload": {
        ...
      }
    },
    ...
  ]
}

Механизм отправления запросов

Запросы обрабатываются каждые 5 секунд, согласно периодической задаче, выполняемой системой.

Вебхук обычно отправляет одно событие за запрос. Однако в следующих случаях может быть отправлен массив событий:

  • Отправка накопленных событий: если за единицу времени (по умолчанию – 5 секунд) произошло несколько событий, они будут отправлены одним запросом;
  • Ретраи (повторные попытки): если сервер не ответил или вернул ошибку на предыдущую попытку, все неуспешные события отправляются повторно единым запросом.

Коды HTTP в диапазоне [200; 299] считаются успешными. Если ответ сервера не входит в этот диапазон, событие считается неуспешным, накапливается и отправляется повторно по следующему расписанию: 1 минута → 5 минут → 30 минут → 3 часа → 12 часов → 24 часа → 48 часов.
Если хотя бы один запрос остается безуспешным через 48 часов, вебхук отключается, и события больше не отправляются.

Управление вебхуками через API

Для управления вебхуками предоставляется API по эндпоинту /api/settings/webhooks со следующими командами:

  • GET /api/settings/webhooks/ — получить список всех вебхуков;
  • POST /api/settings/webhooks/ — создать новый вебхук;
  • GET /api/settings/webhooks/{id}/ — получить информацию по ID;
  • PUT /api/settings/webhooks/{id}/ — полностью обновить данные;
  • PATCH /api/settings/webhooks/{id}/ — частично обновить данные;
  • DELETE /api/settings/webhooks/{id}/ — удалить вебхук по ID;
  • POST /api/settings/webhooks/{id}/refresh_availability_status/ — обновить статус доступности;
  • POST /api/settings/webhooks/test/ — протестировать подключение;
  • GET /api/settings/webhooks/triggers/ — получить список доступных триггеров.

Доступные события

Название события Описание события Значение trigger в запросе Схема payload в запросе
SCA Policy has been triggered Сработала политика при SCA-анализе sca_policy_has_been_triggered
  
"alert_id": 0,
"stage": "dev|source|build|stage|test|prod|proxy",
"level": "info|warning|critical",
"policy_id": 0,
"policy_name": 0,
"dependency_id": 0,
"dependency_purl": "purl",
"matched_criteria": ["matched_criteria", ...],
"project_id": 0
OSA Policy has been triggered Сработала политика при OSA-анализе osa_policy_has_been_triggered
  
"alert_id": 0,
"stage": "dev|source|build|stage|test|prod|proxy",
"level": "info|warning|critical",
"policy_id": 0,
"policy_name": 0,
"dependency_id": 0,
"dependency_purl": "purl",
"matched_criteria": ["matched_criteria", ...],
"container_image_id": 0,
"artifact_repository_id": 0
Project SCA analysis started SCA-анализ проекта был запущен project_sca_analysis_started
  
"project_id": 0,
"project_name": "project_name"
Project SCA analysis finished SCA-анализ проекта был завершён project_sca_analysis_finished
  
"project_id": 0,
"project_name": "project_name",
"vulnerabilities_count": 0,
"dependencies_count": 0
Project SCA analysis cancelled SCA-анализ проекта был отменён project_sca_analysis_cancelled
  
"project_id": 0,
"project_name": "project_name"
Project SCA analysis failed SCA-анализ проекта был завершён с ошибкой project_sca_analysis_failed
  
"project_id": 0,
"project_name": "project_name",
"error": "error_description"
Container Image SCA analysis started SCA-анализ контейнерного образа был запущен container_image_sca_analysis_started
  
"container_image_id": 0,
"container_image_name": "container_image_name"
Container Image SCA analysis finished SCA-анализ контейнерного образа был завершён container_image_sca_analysis_finished
  
"container_image_id": 0,
"container_image_name": "container_image_name",
"vulnerabilities_count": 0,
"dependencies_count": 0
Container Image SCA analysis cancelled SCA-анализ контейнерного образа был отменён container_image_sca_analysis_cancelled
  
"container_image_id": 0,
"container_image_name": "container_image_name"
Container Image SCA analysis failed SCA-анализ контейнерного образа был завершён с ошибкой container_image_sca_analysis_failed
  
"container_image_id": 0,
"container_image_name": "container_image_name",
"error": "error_description"
Clone analysis started Анализ дубликатов проекта был запущен clones_analysis_started
  
"project_id": 0,
"project_name": "project_name"
Clone analysis finished Анализ дубликатов проекта был завершён clones_analysis_finished
  
"project_id": 0,
"project_name": "project_name"
Clone analysis cancelled Анализ дубликатов проекта был отменён clones_analysis_cancelled
  
"project_id": 0,
"project_name": "project_name"
Clone analysis failed Анализ дубликатов проекта был завершён с ошибкой clones_analysis_failed
  
"project_id": 0,
"project_name": "project_name",
"error": "error_description"
Authors analysis started Анализ авторов проекта был запущен authors_analysis_started
  
"project_id": 0,
"project_name": "project_name"
Authors analysis finished Анализ авторов проекта был завершён authors_analysis_finished
  
"project_id": 0,
"project_name": "project_name"
Authors analysis failed Анализ авторов проекта был завершён с ошибкой authors_analysis_failed
  
"project_id": 0,
"project_name": "project_name",
"error": "error_description"
Authors analysis cancelled Анализ авторов проекта был отменён authors_analysis_cancelled
  
"project_id": 0,
"project_name": "project_name"
Cloning of repository started Клонирование репозитория было запущено cloning_of_repository_started
  
"project_id": 0,
"project_name": "project_name",
"repo_url": "repo_url",
"repo_ref_name": "repo_ref_name"
Cloning of repository finished Клонирование репозитория было завершено cloning_of_repository_finished
  
"project_id": 0,
"project_name": "project_name",
"repo_url": "repo_url",
"repo_ref_name": "repo_ref_name"
Cloning of repository failed Клонирование репозитория было завершено с ошибкой cloning_of_repository_failed
  
"project_id": 0,
"project_name": "project_name",
"repo_url": "repo_url",
"repo_ref_name": "repo_ref_name",
"error": "error_description"

Пример простого приложения на Flask

import json

from flask import Flask, request


app = Flask(__name__)

events = []


@app.get('/')
def show_events():
    return f'<pre>{json.dumps(events, indent=2)}</pre>'


@app.post('/')
def handle_events():
    received_events = request.json.get('events', [])
    events.extend(received_events)
    return 'OK'