Skip to content

advisory’s query and pruning functionality#2288

Draft
bxf12315 wants to merge 2 commits intoguacsec:mainfrom
bxf12315:advisory-prune
Draft

advisory’s query and pruning functionality#2288
bxf12315 wants to merge 2 commits intoguacsec:mainfrom
bxf12315:advisory-prune

Conversation

@bxf12315
Copy link
Contributor

@bxf12315 bxf12315 commented Mar 15, 2026

Summary by Sourcery

Introduce shared deletion and prune utilities and add advisory management CLI commands.

New Features:

  • Add advisory CLI commands for listing and pruning advisories using the Trustify API.
  • Expose advisory API module supporting list and prune operations against advisory resources.

Enhancements:

  • Refactor common list/prune parameter types and bulk deletion logic into a shared common module used by SBOM and advisory APIs.
  • Standardize delete result and entry identifier structures across SBOM and advisory deletion flows.
  • Improve SBOM prune implementation to use shared query-building utilities and generalized deletion helper.

Documentation:

  • Extend CLI README with documentation and examples for the new advisory list and advisory prune commands, including output format.

@sourcery-ai
Copy link
Contributor

sourcery-ai bot commented Mar 15, 2026

Reviewer's Guide

Refactors common list/prune/delete logic from the SBOM API into a shared common module and introduces new advisory list/prune CLI commands and API bindings that reuse this infrastructure, while unifying deletion result structures and output formats across SBOMs and advisories.

Sequence diagram for advisory prune command using shared delete_entries

sequenceDiagram
    actor User
    participant Cli as trustify_binary
    participant Cmd as AdvisoryCommands
    participant Api as AdvisoryApi
    participant Common as CommonModule
    participant Client as ApiClient

    User->>Cli: run "trustify advisory prune" with flags
    Cli->>Cmd: parse args to AdvisoryCommands::Prune
    Cmd->>Cmd: build PruneParams from flags
    Cmd->>Api: prune(&ctx.client, &params)

    Api->>Common: build_prune_query(&params)
    Common-->>Api: query, ListParams

    Api->>Client: get_with_query(ADVISORY_PATH, ListParams)
    Client-->>Api: JSON list of advisories
    Api->>Api: parse JSON into items Vec
    Api->>Api: map items to Vec DeleteEntry

    alt params.dry_run == true
        Api-->>Cmd: new_delete_result(total)
    else params.dry_run == false
        Api->>Common: delete_entries(&client, ADVISORY_PATH, entries, params.concurrency)
        Common->>Client: delete("/v2/advisory/{id}") for each entry (concurrent)
        Client-->>Common: Ok or ApiError for each delete
        Common-->>Api: DeleteResult
        Api-->>Cmd: DeleteResult
    end

    Cmd->>Cmd: print summary and optionally write JSON file
    Cmd-->>Cli: ExitCode::SUCCESS
    Cli-->>User: command completes
Loading

Class diagram for shared prune/delete infrastructure and advisory integration

classDiagram
    class ListParams {
        +Option~String~ q
        +Option~u32~ limit
        +Option~u32~ offset
        +Option~String~ sort
    }

    class PruneParams {
        +Option~String~ q
        +Option~u32~ limit
        +Option~DateTime_Local~ published_before
        +Option~i64~ older_than
        +Option~Vec~String~~ label
        +Option~u32~ keep_latest
        +bool dry_run
        +usize concurrency
    }

    class DeleteEntry {
        +String id
        +String identifier
    }

    class DeleteResult {
        +Vec~DeletedResult~ deleted
        +u32 deleted_total
        +Vec~SkippedResult~ skipped
        +u32 skipped_total
        +Vec~FailedResult~ failed
        +u32 failed_total
        +u32 total
    }

    class DeletedResult {
        +String id
        +String identifier
    }

    class SkippedResult {
        +String id
        +String identifier
    }

    class FailedResult {
        +String id
        +String identifier
        +String error
    }

    class CommonModule {
        +build_prune_query(params: PruneParams) String,ListParams
        +delete_entries(client: ApiClient, base_path: String, entries: Vec~DeleteEntry~, concurrency: usize) DeleteResult
        +new_delete_result(total: u32) DeleteResult
    }

    class ApiClient {
        +get_with_query(path: String, params: ListParams) Result~String,ApiError~
        +delete(path: String) Result~(),ApiError~
    }

    class SbomApi {
        +const SBOM_PATH: &str
        +list(client: ApiClient, params: ListParams) Result~String,ApiError~
        +prune(client: ApiClient, params: PruneParams) Result~DeleteResult,ApiError~
        +delete_by_query(client: ApiClient, params: ListParams, dry_run: bool, concurrency: usize) Result~DeleteResult,ApiError~
        +delete_list(client: ApiClient, entries: Vec~DeleteEntry~, concurrency: usize) Result~DeleteResult,ApiError~
        +read_delete_entries_from_file(input_file: String) Result~Vec~DeleteEntry~,ApiError~
        +delete_duplicates(client: ApiClient, input_file: String, dry_run: bool, concurrency: usize) Result~DeleteResult,ApiError~
    }

    class AdvisoryApi {
        +const ADVISORY_PATH: &str
        +list(client: ApiClient, params: ListParams) Result~String,ApiError~
        +prune(client: ApiClient, params: PruneParams) Result~DeleteResult,ApiError~
    }

    class Commands {
        +Sbom command
        +Advisory command
        +Auth command
        +run(ctx: Context) ExitCode
    }

    class SbomCommands {
        +List
        +Prune
        +run(ctx: Context) ExitCode
    }

    class AdvisoryCommands {
        +List
        +Prune
        +run(ctx: Context) ExitCode
    }

    class ListFormat {
        +Full
    }

    class OutputFormat {
        +Json
    }

    CommonModule --> ListParams
    CommonModule --> PruneParams
    CommonModule --> DeleteEntry
    CommonModule --> DeleteResult
    DeleteResult --> DeletedResult
    DeleteResult --> SkippedResult
    DeleteResult --> FailedResult

    SbomApi ..> CommonModule : uses
    SbomApi --> ListParams
    SbomApi --> PruneParams
    SbomApi --> DeleteResult
    SbomApi --> DeleteEntry

    AdvisoryApi ..> CommonModule : uses
    AdvisoryApi --> ListParams
    AdvisoryApi --> PruneParams
    AdvisoryApi --> DeleteResult
    AdvisoryApi --> DeleteEntry

    CommonModule --> ApiClient

    Commands --> SbomCommands
    Commands --> AdvisoryCommands

    SbomCommands --> ListParams
    SbomCommands --> PruneParams

    AdvisoryCommands --> ListParams
    AdvisoryCommands --> PruneParams
    AdvisoryCommands --> ListFormat
    AdvisoryCommands --> OutputFormat

    AdvisoryCommands --> AdvisoryApi
    SbomCommands --> SbomApi
Loading

File-Level Changes

Change Details Files
Extract shared list, prune parameter handling, and concurrent delete logic into a reusable common module used by both SBOM and advisory APIs.
  • Introduce common module with ListParams, PruneParams, and query-building helper build_prune_query used for pruning operations.
  • Add generic deletion types DeleteEntry, DeleteResult, and helpers delete_entries and new_delete_result that encapsulate progress reporting and concurrent deletion.
  • Update SBOM API code to import these shared types/helpers and replace inlined prune query construction and delete-list implementation with calls into the common module, including renaming document_id to identifier in deletion entries and results.
etc/trustify-cli/src/common/mod.rs
etc/trustify-cli/src/api/sbom.rs
etc/trustify-cli/src/commands/sbom.rs
Add new advisory management CLI commands (list and prune) wired to a new advisory API client that mirrors SBOM behaviour using the shared common utilities.
  • Introduce AdvisoryCommands enum with list and prune subcommands, including CLI flags for filtering, pagination, prune criteria, concurrency, dry-run, output options, and quiet mode.
  • Implement advisory API module providing list and prune functions that call the /v2/advisory backend, parse responses, and construct DeleteEntry lists for deletion using delete_entries.
  • Wire advisory commands into the top-level command dispatcher and main CLI module so trustify advisory list and trustify advisory prune are available.
etc/trustify-cli/src/commands/advisory.rs
etc/trustify-cli/src/api/advisory.rs
etc/trustify-cli/src/commands/mod.rs
etc/trustify-cli/src/api/mod.rs
etc/trustify-cli/src/main.rs
Update user-facing documentation and output schemas to reflect the new advisory commands and the unified delete result structure.
  • Extend CLI README with sections for advisory list and advisory prune, including usage examples and the JSON output format of prune results.
  • Align delete result JSON fields to id and identifier (instead of SBOM-specific names), and ensure types derive Serialize and Deserialize for file output and parsing.
etc/trustify-cli/README.md
etc/trustify-cli/src/common/mod.rs
etc/trustify-cli/src/api/sbom.rs

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@bxf12315 bxf12315 requested a review from ruromero March 15, 2026 13:16
@bxf12315
Copy link
Contributor Author

@ruromero In order to implement operations related to advisories, I refactored the existing code. Please review them.

@bxf12315 bxf12315 changed the title Advisory prune advisory’s query and pruning functionality Mar 15, 2026
Copy link
Contributor

@ruromero ruromero left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The functional changes look good to me and seems a reasonable refactoring

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

2 participants