Markup2: Difference between revisions

From Svacer Wiki
mNo edit summary
mNo edit summary
Line 75: Line 75:
Актуальную версию схемы можно получить из Svacer по API: <code>GET /api/public/markup/schema</code>.
Актуальную версию схемы можно получить из Svacer по API: <code>GET /api/public/markup/schema</code>.


'''ВНИМАНИЕ''': При сериализации в JSON используются proto-имена полей.
'''ВНИМАНИЕ''': При сериализации в JSON используются proto-имена полей. При работе с данными из Go рекомендуется использовать https://pkg.go.dev/google.golang.org/protobuf/encoding/protojson для сериализации и десериализации.


Svacer поддерживает два формата для экспортирования/импортирования разметки:
Svacer поддерживает два формата для экспортирования/импортирования разметки:

Revision as of 13:11, 18 November 2024

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

Пользователь должен указать либо source элемент, либо source_id.

Опция skip_comments позволяет игнорировать комментарии при выгрузке разметки.

Опция skip_review позволяет игнорировать статусы маркеров при выгрузке разметки (т.е выгружать только комментарии).

Метод возвращает 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, то разметка будет перезаписана если загруженная разметка имеет более новую дату.
  • Сформированный список применяется к бранчу. При выборе маркера, куда добавлять комментарий, выбирается маркер из наиболее раннего снимка, где маркер с соответствующим инвариантом появился.

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

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 --help copy --help
svacer markup2 --help import --help
svacer markup2 --help 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)
   --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"}}}