Markup2
Public REST API для экспорта, импорта и копирования разметки
Релиз 10.х Svacer включает новый API предназначенный для экспорта, импорта и копирования разметки. API доступен по endpoint-ам
POST /api/public/markup/import POST /api/public/markup/export POST /api/public/markup/copy
Разметка описывается посредством protobuf схемы:
// Represents exported review (review itself + comments) // Review is associated with invariant and has list of locations message Review { // Defines model for concrete location of the review message Location { string warnClass = 1; string file = 2; uint32 line = 3; string details = 4; string mtid = 5; string function = 10; bytes content_hash = 6; bytes trace_hash = 7; bytes marker_hash = 8; bytes line_hash = 9; string tool = 11; string lang = 12; } // Defines model for comment message Comment { string text = 1; optional string format = 2; google.protobuf.Timestamp create_ts = 3; optional google.protobuf.Timestamp update_ts = 4; string createdBy = 5; string origin_id = 6; optional uint64 review_id = 7; // refers to Review.id field optional string created_by_id = 8; } // Defines model for review itself message ReviewData { string status = 1; string severity = 2; string action = 3; string origin_id = 4; google.protobuf.Timestamp create_ts = 5; string created_by = 6; optional string created_by_id = 7; optional string created_from = 8; } // Invariant of the marker string invariant = 1; // Review information associated with markers having given invariant optional ReviewData review_data = 2; // List of comments associated with all markers having given invariant repeated Comment comments = 3; // List of locations associated with given invariant. Locations can be used to apply fuzzy matching of review with existing data when there is no invariant match repeated Location locations = 4; // Export-specific ID, comments can refer to this id if comment is associated with review operation uint64 id = 5; // Meta-information about export, when exporting to file field is initialized only for the first element optional ReviewExportMeta meta = 6; } // Defines meta-information about exported review message ReviewExportMeta { message Container { string id = 1; string name = 2; } google.protobuf.Timestamp create_ts = 1; // timestamp when export was produced (UTC) string created_by = 2; // user who triggered export string svacer_version = 3; // svacer version optional Container project = 4; // source container (project) optional Container branch = 5; // source container (branch) map<string,string> properties = 6; // extra properties }
Актуальную версию схемы можно получить из Svacer по API: GET /api/public/markup/schema
.
ВНИМАНИЕ: При сериализации в JSON используются proto-имена полей. При работе с данными из Go рекомендуется использовать https://pkg.go.dev/google.golang.org/protobuf/encoding/protojson для сериализации и десериализации.
Svacer поддерживает два формата для экспортирования/импортирования разметки:
json
с разделением по newline-ам. Каждая строка представляет собой объект типаReview
(указано выше) сериализованный в JSON- бинарный формат: последовательность блоков
[lenght little endian][proto]
, где первый блок содержит длину следующего блока в форматеu32 little endian
, а второй блок содержит proto-сериализацию объектаReview
В обоих случаях при выгрузке разметки первый элемент типа Review
будет содержать мета-информацию об исходном контексте, откуда была выгружена разметка
Разметка привязывается к инварианту маркера и может содержать собственно разметку (статус маркера) и совокупность комментариев, связанных с данным маркером. При выгрузке разметки так же добавляется информация о конкретных локациях предупреждений, ассоциированных с инвариантом. В будущих версиях данная информация будет использоваться для переноса разметки при отсутствии прямого совпадения инвариантов.
Экспорт разметки
POST /api/public/markup/export
- параметры передаются в body запроса
- запрос должен иметь токен аутентификации
- пользователь должен иметь доступы на Public API и экспорт разметки из ветки, откуда производится экспорт
Формат body:
{ "source": ["<project name>","<branch name>"], "source_id": "<branch id>", "skip_comments": <true|false>, "skip_review": <true|false>, "format": "<json|proto>", "export_all": <true|false> }
Пользователь должен указать либо source
элемент, либо source_id
.
Опция skip_comments
позволяет игнорировать комментарии при выгрузке разметки.
Опция skip_review
позволяет игнорировать статусы маркеров при выгрузке разметки (т.е выгружать только комментарии).
Опция export_all
позволяет выгрузить пустую разметку (т.е статусы Undecided/Unspecified/Undecided). Это позволяет получить список всех инвариантов для ветки и использовать данные для генерации требуемой разметки для импорта.
Метод возвращает gzipped файл содержащий разметку в указанном формате.
Импорт разметки
POST /api/public/markup/import
- параметры передаются в query запроса
- запрос должен быть формата
multipart/form-data
, полеfile
должно содержать файл с разметкой - запрос должен иметь токен аутентификации
- пользователь должен иметь доступы на Public API, импорт разметки или снэпшота и разрешения
Update any review
иUpdate any comment
Query параметры:
project - <project name> - имя проекта branch - <branch name> - имя бранча target_id - <branch id> - id бранча. Должно быть либо id бранча, либо имя проекта + имя бранча. Приоритет - id бранча format - <proto|json> - формат импортируемой разметки, если не указан - будет определяться автоматически overwrite - <none|force|last> - контролирует логику применения разметки к бранчу при импорте skip_comments - <true|false> - игнорировать комментарии skip_review - <true|false> - игнорировать статус разметки (импорт только комментариев) response_with_result - <true|false> - вернуть детальный список разметок, какие были применены в формате json с newline разделителями. Если не указан, то возвращается краткий статус compressed - <true|false> - формат файла с разметкой, если true то файл подразумевается gzip-compressed
В случае успеха, метод возвращает Body со следующими данными
{"total":<total number of loaded reviews>,"applied_reviews":<applied reviews>,"applied_comments":<applied comments>,"skipped_reviews":<skipped reviews>,"duplicate_reviews":<duplicate reviews>,"duplicate_comments":<duplicate comments} <json representation of applied review>*
Первая строка Body содержит JSON с информацией о выполненных действиях. Если бы указан параметр response_with_result
то дальше будут идти newline-separated JSON представления примененных review.
Алгоритм импорта
- Блокируются операции по разметки и импорту на целевой бранч
- Выгружается текущая разметка бранча с комментариями
- Загруженная разметка сопоставляется с текущей и формируется список разметки для применения. Дублирующая разметка и комментарии игнорируются. Перезапись разметки контролируется параметрами
overwrite
. Если значениеnone
, то разметка не перезаписывается при наличии разметки в целевом бранче. Если значениеforce
, то разметка будет перезаписана. Если значениеlast
, то разметка будет перезаписана если загруженная разметка имеет более новую дату. - Пустая разметка (Undecided/Unspecified/Undecided) явным образом не применяется к инварианту, если разметка отсутствует на бранче
- Сформированный список применяется к бранчу. При выборе маркера, куда добавлять комментарий, выбирается маркер из наиболее раннего снимка, где маркер с соответствующим инвариантом появился.
Допустимые значения полей разметки:
- Status -
"Confirmed", "Won't fix", "False Positive", "Unclear", "Undecided"
- Severity -
"Unspecified", "Critical", "Major", "Minor"
- Action -
"Undecided", "Fix required", "Fix submitted", "Ignore"
Копирование разметки
POST /api/public/markup/copy
- параметры передаются в body запроса
- запрос должен иметь токен аутентификации
- пользователь должен иметь доступы на Public API, импорт разметки/снимка и разрешения
Update any review
иUpdate any comment
Формат body:
{ "source": ["<project name>","<branch name>"], "source_id": "<branch id>", "target": ["<project name>","<branch name>"], "target_id": "<branch id>", "skip_comments": <true|false>, "skip_review": <true|false>, "overwrite": "<none|last|force>", "response_with_result": <true|false> }
В случае успеха, метод возвращает Body со следующими данными
{"total":<total number of loaded reviews>,"applied_reviews":<applied reviews>,"applied_comments":<applied comments>,"skipped_reviews":<skipped reviews>,"duplicate_reviews":<duplicate reviews>,"duplicate_comments":<duplicate comments} <json representation of applied review>*
Первая строка Body содержит JSON с информацией о выполненных действиях. Если бы указан параметр response_with_result
то дальше будут идти newline-separated JSON представления примененных review.
CLI API для импорта/экспорта/копирования разметки
Данное API является экспериментальным и может меняться. Основные аргументы будут сохранены. По умолчанию, команды под markup2
скрыты. Использовать можно, указывая их явно. Для получения помощи запустить:
svacer markup2 --help svacer markup2 copy --help svacer markup2 import --help svacer markup2 export --help
Описание команд:
NAME: svacer markup2 - New [experimental] API for review export/import/copy USAGE: svacer markup2 command [command options] [arguments...] COMMANDS: import Import markup from file and apply to specified branch export Export markup to file or stdout. Command needs either branch ID or project and branch name. When exporting to file, data is gzipped. copy Copy markup between branches help, h Shows a list of commands or help for one command OPTIONS: --ssl Connect to the server using https protocol (default: false) --ssl-ca-certs value Trusted CA cert path. Example: /usr/local/certs/* , /usr/local/certs/ca.crt, /usr/local/certs/ca*.crt --user value Valid user name --password value Valid user password --oidc-client value ClientID for login with OpenID Connect protocol --oidc-secret value Client's secret for login with OpenID Connect protocol --host value Valid host name with running svace history server (default: localhost) [$SVACER_HOST_NAME] --port value Defines port for REST API (default: 8080) [$SVACER_API_PORT] --grpc value Defines port for gRPC API (default: 3002) [$SVACER_GRPC_PORT] --ldap_server value Server for LDAP authentication [$SVACER_LDAP_SERVER] --conn_file value Use connection file [$SVACER_CONN_FILE] --dry-run Do actions but don't commit result to database (default: false) --help Show help (default: false)
Импорт разметки из файла
NAME: svacer markup2 import - Import markup from file and apply to specified branch USAGE: svacer markup2 import [command options] <file> - path to file to import. If file is not specified, data is loaded from stdin OPTIONS: --project value Target project name --branch value Target branch name --branch-id value Target branch ID --skip-review Import comments only (default: false) --skip-comments Import review only (default: false) --overwrite value Overwrite mode: none, force, last --out value Write information about applied reviews to given file (in json format). If not specified, result is printed to stdout --verbose-out Include information about applied reviews (default: false) --format value Specify explicit format for data. If not specified, format will be detected from content --help Show help (default: false)
Экспорт разметки в файл
NAME: svacer markup2 export - Export markup to file or stdout. Command needs either branch ID or project and branch name. When exporting to file, data is gzipped. USAGE: svacer markup2 export [command options] <file name or empty> - if no file name is specified, result is printed to stdout OPTIONS: --project value Source project name --branch value Source branch name. Branch name will be resolved against source project --branch-id value Source branch ID --skip-review Export comments only (default: false) --skip-comments Export review only (default: false) --format value Format: json or proto. If format is not specified, proto is used. If output file is not specified and format is not specified, json will be used. --uncompressed Get data in raw format without gzip compression (default: false) --export-all Export empty (undecided) review (default: false) --help Show help (default: false)
Копирование разметки
NAME: svacer markup2 copy - Copy markup between branches USAGE: svacer markup2 copy [command options] [arguments...] OPTIONS: --target-project value Target project name --target-branch value Target branch name --target-branch-id value Target branch ID --source-project value Source project name --source-branch value Source branch name --source-branch-id value Source branch ID --skip-review Copy comments only (default: false) --skip-comments Copy review only (default: false) --overwrite value Overwrite mode: none, force, last --out value Write information about applied reviews to given file (in json format). If not specified, result is printed to stdout --verbose-out Include information about applied reviews (default: false) --help Show help (default: false)
Примеры использования:
svacer markup2 --user admin --password admin copy --overwrite=force --source-project bash --target-project bash --source-branch master --target-branch bash_clone 2024-11-15T13:19:41.735+0300 info Log file location /tmp/svacer-1543671068.log 2024-11-15T13:19:41.735+0300 info Quering server configuration from http://localhost:8080/api/public/server/info 2024-11-15T13:19:41.745+0300 info Server version: [devel] {"total":771,"applied_reviews":0,"applied_comments":0,"skipped_reviews":771,"duplicate_reviews":771,"duplicate_comments":5}
svacer markup2 --user admin --password admin import --overwrite=force --project bash --branch bash_clone /tmp/out.json 2024-11-15T13:20:17.433+0300 info Log file location /tmp/svacer-1480510331.log 2024-11-15T13:20:17.433+0300 info Quering server configuration from http://localhost:8080/api/public/server/info 2024-11-15T13:20:17.435+0300 info Server version: [devel] {"total":771,"applied_reviews":0,"applied_comments":0,"skipped_reviews":771,"duplicate_reviews":771,"duplicate_comments":5}
2024-11-15T15:46:06.809+0300 info Log file location /tmp/svacer-1792255677.log 2024-11-15T15:46:06.809+0300 info Quering server configuration from http://localhost:8080/api/public/server/info 2024-11-15T15:46:06.810+0300 info Server version: [devel] {"invariant":"+1vB4JXkME3AAcbXR7tezA", "review_data":{"status":"Confirmed", "severity":"Unspecified", "action":"Undecided", "create_ts":"2024-10-16T14:44:07.233554Z", "created_by":"admin", "created_from":"1c8cea92-7708-4bb9-9a88-40325f39efe8"}, "locations":[{"warnClass":"PROC_USE.VULNERABLE", "file":"/.build/jobs.c", "line":4207, "details":"b043c5a63bf9d432c816f2cb421c907fe912bf16", "mtid":"SvEng.L.1", "function":"run_sigchld_trap", "content_hash":"s4AMYzKR8Ol8k4OODPpOlPUsSWI=", "marker_hash":"XiVQmRu8HmhzOnq1+XY7AaujT+o=", "tool":"SvEng", "lang":"C_Cpp"}], "id":"699", "meta":{"create_ts":"2024-11-15T12:46:06.835078490Z", "created_by":"admin", "svacer_version":"devel.2024-11-15@15:45:34.a290bc7e", "project":{"id":"0fd645aa-8e70-4a4f-b68b-766c4f337bf2", "name":"bash"}, "branch":{"id":"8925df5a-7a98-4f07-bc88-ee4ea5b43813", "name":"master"}}}