Markup2: Difference between revisions

From Svacer Wiki
mNo edit summary
Line 199: Line 199:
Первая строка body содержит JSON с информацией о выполненных действиях. Если был указан параметр '''response_with_result''', то дальше будут идти newline-separated JSON представления примененных review.
Первая строка body содержит JSON с информацией о выполненных действиях. Если был указан параметр '''response_with_result''', то дальше будут идти newline-separated JSON представления примененных review.


== Журнал групповых операций ==
== Журнал групповых операций (для версии 11.х.х и выше) ==
Импорт разметки а также использование групповой разметки (из UI или посредством API) фиксирует операции в журнале групповых операций. Для работы с журналом доступно public REST API:
Импорт разметки а также использование групповой разметки (из UI или посредством API) фиксирует операции в журнале групповых операций. Для работы с журналом доступно public REST API:



Revision as of 14:27, 14 May 2025

Public REST API для экспорта, импорта и копирования разметки

Релиз 10.х Svacer включает новый API, предназначенный для экспорта, импорта и копирования разметки.

Релиз 11.х Svacer добавил журнал групповых операций связанных с импортом разметки и возможность отката внесенных изменений. Для журнала групповых операций доступно public API.

# Импорт, экспорт и копирование разметки
POST /api/public/markup/import
POST /api/public/markup/export
POST /api/public/markup/copy

# Работа с журналом групповых операций по разметки
GET /api/public/markup/list_operations
DELETE /api/public/markup/list_operations
POST /api/public/markup/undo

Разметка описывается посредством 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 рекомендуется использовать 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>,
    "compressed": <true|false>,
    "filters" : [ {
       "pattern": "<regular expression>",
       "ids": ["<snapshot id>", "<snapshot id>"]
     }
    ]
}
  • Пользователь должен указать либо source элемент, либо source_id
  • Опция skip_comments позволяет игнорировать комментарии при выгрузке разметки
  • Опция skip_review позволяет игнорировать статусы маркеров при выгрузке разметки (т. е. выгружать только комментарии)
  • Опция export_all позволяет выгрузить пустую разметку (т. е. статусы Undecided/Unspecified/Undecided). Это позволяет получить список всех инвариантов для ветки и использовать данные для генерации требуемой разметки для импорта
  • Метод возвращает gzipped файл содержащий разметку в указанном формате если compressed = true
  • Поле filters позволяет указать набор фильтров для снимков. Все фильтры применяются по принципу AND. Поле pattern в фильтре задает фильтрацию по имени снимка, поле ids — по ID снимков.

Импорт разметки

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> — по умолчанию last — контролирует логику применения разметки к бранчу при импорте
skip_comments — <true|false> — по умолчанию false — игнорировать комментарии
skip_review — <true|false> — по умолчанию false — игнорировать статус разметки (импорт только комментариев)
response_with_result — <true|false> — вернуть детальный список разметок, которые были применены, в формате JSON с newline-разделителями. Если не указан, то возвращается краткий статус
compressed — <true|false> — формат файла с разметкой, если true то подразумевается gzip-compressed файл

Настоятельно рекомендуется явно указывать параметр overwrite.

В случае успеха метод возвращает 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> — по умолчанию false,
    "skip_review": <true|false> — по умолчанию 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.

Журнал групповых операций (для версии 11.х.х и выше)

Импорт разметки а также использование групповой разметки (из UI или посредством API) фиксирует операции в журнале групповых операций. Для работы с журналом доступно public REST API:

# Получения списка групповых операций
GET /api/public/markup/list_operations
# Удаление записи из журнала групповых операций
DELETE /api/public/markup/list_operations
# Отмена изменений, внесенных групповой операцией
POST /api/public/markup/undo

Описание параметров доступно в Swagger.

Семантика операции Undo следующая:

  • Разметка, внесенная групповой операцией удаляется. Если она была активной, то ставится предыдущая активная разметка
  • Комментарии, внесенные групповой операцией, будут удалены только если они не модифицировались после групповой операции
  • По умолчанию при отмене операции происходит проверка, является ли она последней групповой операцией на данной ветке. Если она не является последней, то будет ошибка (для принудительной отмены используется параметр check_order)

Для экономии памяти рекомендуется периодически удалять записи из журнала групповых операций.

CLI API для импорта/экспорта/копирования разметки

Данное API является экспериментальным и может меняться. Основные аргументы будут сохранены. По умолчанию команды под markup2 скрыты. Использовать можно, указывая их явно. Для получения помощи запустить:

# Импорт, экспорт, копирование разметки
svacer markup2 --help
svacer markup2 copy --help
svacer markup2 import --help
svacer markup2 export --help
# Работа с журналом групповых операций
svacer markup2 list --help
svacer markup2 undo --help
svacer markup2 delete --help

Описание работы с журналом групповых операций

При использовании операций по импорту разметки или использовании API/UI для выполнения групповых операций по разметке информация о выполненных операциях будет занесена в журнал групповых операций. Журнал фиксирует дату, пользователя и все внесенные изменения: изменение самой разметки и добавленные комментарии.

Просмотр журнала операций:
svacer markup2 --host <host url> --user admin --password admin list
id  status   target                               action         description                                                                                                                                                                                                                         ts                                    user      
94  APPLIED  local/b1                             import-review  import comments as part of raw result import                                                                                                                                                                                        2025-04-24 13:19:30.675 +0300 MSK     admin     
91  APPLIED  bash/master                          batch-review   batch review operation                                                                                                                                                                                                              2025-04-18 16:09:17.963822 +0300 MSK  admin     
89  APPLIED  dxr-test/master                      batch-review   batch review operation                                                                                                                                                                                                              2025-04-18 14:21:42.82489 +0300 MSK   admin     
87  APPLIED  Lua_clone2/v5.3                      copy-review    copy review from 61c4290b-d06a-484f-b980-8d7cbb660fb4 to 0588686d-a1da-4f11-b948-d07a9d12fb60                                                                                                                                       2025-04-18 12:57:09.49 +0300 MSK      admin     
86  APPLIED  Lua_clone1/v5.3                      import-review  import review by request from WEB or REST API; client address: 10.10.168.102:52020, user agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 YaBrowser/25.2.0.0 Safari/537.36  2025-04-18 12:54:17.239 +0300 MSK     admin     
85  APPLIED  Lua/v5.3                             batch-review   batch review operation                          
Отмена операции:
svacer markup2 --host localhost:8080 --user admin --password admin undo --id=94


2025-05-14T11:47:33.559+0300    info    Log file location /tmp/svacer-client-2025-05-14.log
2025-05-14T11:47:33.560+0300    info    Scheme not found in the provided host (localhost:8080), assume 'http'
2025-05-14T11:47:33.560+0300    info    Querying server configuration from http://localhost:8080/api/public/server/info
2025-05-14T11:47:33.560+0300    info    Server version: [11-0-0]
2025-05-14T11:47:33.599+0300    info    Unapplied batch review operations [94]
Удаление записей из журнала

ВНИМАНИЕ: Удаление записей из журнала не отменяет внесенных изменений (т.е разметки и комментариев), но после удаление записей из журнала отмена соответствующих изменений будет невозможна.

Для удаления можно использовать разный набор условий

NAME:
   svacer markup2 delete - Delete entries from batch review operation list. ATTENTION: you cannot undo batch operation if you remove it

USAGE:
   svacer markup2 delete [command options] [arguments...]

DESCRIPTION:
   When multiple flags are used to specify conditions, all conditions will be applied in order: --id, (--from, --to), --keep-last-n
   Flag --last will override values of --from and --to


OPTIONS:
   --id value [ --id value ]  ID of the batch operation
   --from value               Set start date for the report. Expected format '2006-01-02 15:04:05' in local timezone
   --to value                 Set end date for the report. Expected format '2006-01-02 15:04:05' in local timezone
   --last value               Delete operations for the specified last period of time. Possible values: @hour, @day, @week, @month, @year
   --keep-last-n value        Keep last N entries (default: 0)
   --help                     Show help (default: false)

Пример, оставим последние 10 операций в журнале

svacer markup2 --host localhost:8080 --user admin --password admin delete --keep-last-n 10
2025-05-14T11:51:31.121+0300    info    Log file location /tmp/svacer-client-2025-05-14.log
2025-05-14T11:51:31.121+0300    info    Scheme not found in the provided host (localhost:8080), assume 'http'
2025-05-14T11:51:31.121+0300    info    Querying server configuration from http://localhost:8080/api/public/server/info
2025-05-14T11:51:31.122+0300    info    Server version: [11-0-0]
2025-05-14T11:51:31.146+0300    info    Deleted 37 entries from the list

Описание команд импорта, экспорта и копирования

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
   --description value   Specify optional description the given import operation. If not specified, unique ID will be generated based on hostname, user and time
   --generated-by value  Optional tool generated review information
   --help             Show help (default: false)

При импорте разметки используя флаги --description и --generated-by можно задать дополнительную информацию, связанную с данной разметкой. Она будет занесена в журнал операций импорта.

Экспорт разметки в файл

NAME:
   svacer markup2 export - Export markup to file or stdout. Command needs either branch ID or project and branch name.  Use --snapshot-id and --snapshot to filter results by snapshots (filters are applied by AND rule)

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 (default: master)
   --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)
   --snapshot-id value [ --snapshot-id value ]  Filter results by snapshots with specified IDs. When using --snapshot flag, results will be filtered by name pattern as well
   --snapshot value                             Filter results by snapshots matching pattern. Pattern is matched against snapshot name. When using --snapshot-id flag, results will be filtered by ID as well
   --help    

Для экспорта разметки из конкретных снимков можно использовать флаги --snapshot-id или --snapshot.

Копирование разметки

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"}}}