Skip to content

feat: repo file fields sanitization - #1859

Open
pindo696 wants to merge 7 commits into
RedHatInsights:masterfrom
pindo696:repo-sanitization-checks
Open

feat: repo file fields sanitization#1859
pindo696 wants to merge 7 commits into
RedHatInsights:masterfrom
pindo696:repo-sanitization-checks

Conversation

@pindo696

@pindo696 pindo696 commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Little sanitization for repo files during parsing process. Supporting test files taken and modified from vmaas-data repository. Metrics for initial behavior observation. Modified tests. Part of RHINENG-13437

Secure Coding Practices Checklist GitHub Link

Secure Coding Checklist

  • Input Validation
  • Output Encoding
  • Authentication and Password Management
  • Session Management
  • Access Control
  • Cryptographic Practices
  • Error Handling and Logging
  • Data Protection
  • Communication Security
  • System Configuration
  • Database Security
  • File Management
  • Memory Management
  • General Coding Practices

Summary by Sourcery

Introduce validation and sanitization for repository metadata fields and expose new validation metrics for observability.

New Features:

  • Add centralized metadata validation utilities for CVE IDs, Bugzilla IDs, architectures, package names, versions, and releases.
  • Track validation successes and failures across primary, primary_db, updateinfo, and repository list processing using Prometheus counters.
  • Visualize repository validation failures in Grafana via a new panel query and updated dashboard configuration.

Bug Fixes:

  • Prevent importing repositories with invalid base architectures and skip invalid packages and errata entries during metadata parsing.

Enhancements:

  • Refactor primary, primary_db, and updateinfo parsers to validate key fields and skip invalid records while logging warnings.
  • Initialize valid architectures from the database at startup to enforce architecture whitelisting consistently across components.
  • Update CVE reference IDs in test data to use proper CVE formats and extend tests to cover validation behavior and error handling.
  • Upgrade Grafana dashboard schema, plugin versions, and threshold configurations for compatibility with the new metrics.

Tests:

  • Add unit tests for metadata validators, repository controller basearch handling, and updateinfo/primary parsing of valid and invalid data.
  • Extend existing repository and updateinfo tests with new validation-focused scenarios and supporting XML test data files.

@sourcery-ai

sourcery-ai Bot commented Jul 14, 2026

Copy link
Copy Markdown

Reviewer's Guide

Adds centralized validation and sanitization for repository metadata (packages, errata, references, architectures), wires failures into Prometheus metrics and Grafana dashboards, and extends tests plus fixtures to cover validation behavior and repository basearch handling.

Sequence diagram for updateinfo errata and package validation

sequenceDiagram
    participant UpdateInfoMD
    participant XMLUpdate as update_elem
    participant Validators as metadata_validators
    participant Metrics as VALIDATION_FAILED_ITEMS
    participant Logger

    UpdateInfoMD->>XMLUpdate: iterparse(filename)
    XMLUpdate-->>UpdateInfoMD: <update> end event
    UpdateInfoMD->>UpdateInfoMD: _parse_update(elem)
    UpdateInfoMD->>UpdateInfoMD: _process_package(pkg, module)
    UpdateInfoMD->>UpdateInfoMD: _validate(name, name)
    UpdateInfoMD->>Validators: validate_field(value, field_type)
    alt validation fails
        Validators-->>UpdateInfoMD: raise ValidationError
        UpdateInfoMD->>Metrics: labels(metadata_type=updateinfo, field=field_type).inc()
        UpdateInfoMD->>Logger: warning("Validation failed, skipped: %s", err)
        UpdateInfoMD-->>UpdateInfoMD: skip current update
    else validation succeeds
        Validators-->>UpdateInfoMD: validated value
        UpdateInfoMD-->>UpdateInfoMD: append package to update["pkglist"]
        UpdateInfoMD-->>UpdateInfoMD: append update to updates
    end
Loading

File-Level Changes

Change Details Files
Introduce reusable metadata validation utilities and wire them into package/errata parsing with metrics and logging on failures.
  • Add metadata_validators module with CVE, Bugzilla, architecture, package name, version, and release validators plus a generic validate_field dispatcher and ValidationError type.
  • Initialize the architecture whitelist for validators from DB arch values at startup in production code and via a static list in tests.
  • Refactor PrimaryMD, PrimaryDatabaseMD, and UpdateInfoMD to validate NEVRA fields and selected reference IDs, skipping invalid records, logging warnings, and incrementing validation Prometheus counters.
vmaas/reposcan/repodata/metadata_validators.py
vmaas/reposcan/database/repository_store.py
vmaas/reposcan/repodata/primary.py
vmaas/reposcan/repodata/primary_db.py
vmaas/reposcan/repodata/updateinfo.py
vmaas/reposcan/conftest.py
vmaas/reposcan/mnm.py
Validate repository basearch when queueing repositories and surface validation statistics via Prometheus and Grafana.
  • Add basearch validation in RepositoryController.add_repository, counting validation attempts and failures and skipping invalid repositories with a warning.
  • Stop creating new basearch rows in the database, instead requiring them to exist in the arch map and raising on invalid values.
  • Expose new validation counters through the shared Prometheus registry and add a Grafana panel plus dashboard tweaks (schema/plugin upgrades, threshold value fields, showValues flags).
vmaas/reposcan/repodata/repository_controller.py
vmaas/reposcan/database/repository_store.py
vmaas/reposcan/main.py
monitoring/grafana/dashboards/grafana-dashboard-clouddot-insights-vmaas.configmap.yml
Add and adjust tests and fixtures to cover validation behavior for packages, errata, and repositories.
  • Extend updateinfo tests to cover valid/invalid errata, reference validation, and validate_field error behavior.
  • Add a new validator-focused test module for CVE IDs, Bugzilla IDs, architectures, package names, versions, and releases.
  • Add repository controller tests for basearch validation behavior and update XML fixtures for primary and updateinfo metadata to include valid and invalid records plus corrected CVE IDs.
vmaas/reposcan/repodata/test/test_updateinfo.py
vmaas/reposcan/repodata/test/test_repository.py
vmaas/reposcan/repodata/test/test_validators.py
vmaas/reposcan/test_data/repodata/updateinfo.xml
vmaas/reposcan/test_data/repodata/update_validation_errata_test.xml
vmaas/reposcan/test_data/repodata/primary_validation_test.xml
vmaas/reposcan/test_data/repodata/update_validation_test.xml

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

@pindo696
pindo696 force-pushed the repo-sanitization-checks branch 2 times, most recently from f25ce11 to e12bd9a Compare July 15, 2026 08:22
@codecov-commenter

codecov-commenter commented Jul 15, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 91.35802% with 14 lines in your changes missing coverage. Please review.
✅ Project coverage is 55.00%. Comparing base (5a56460) to head (22509f4).
⚠️ Report is 810 commits behind head on master.

Files with missing lines Patch % Lines
vmaas/reposcan/repodata/primary.py 80.00% 5 Missing ⚠️
vmaas/reposcan/repodata/primary_db.py 72.22% 5 Missing ⚠️
vmaas/reposcan/main.py 0.00% 2 Missing ⚠️
vmaas/reposcan/database/repository_store.py 83.33% 1 Missing ⚠️
vmaas/reposcan/repodata/metadata_validators.py 97.82% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1859      +/-   ##
==========================================
- Coverage   62.98%   55.00%   -7.98%     
==========================================
  Files          70       93      +23     
  Lines        6800     6328     -472     
==========================================
- Hits         4283     3481     -802     
- Misses       2517     2822     +305     
- Partials        0       25      +25     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@pindo696
pindo696 force-pushed the repo-sanitization-checks branch 5 times, most recently from bfe5a69 to 087af13 Compare July 20, 2026 13:01
@pindo696

Copy link
Copy Markdown
Contributor Author

@sourcery-ai review

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Hey - I've left some high level feedback:

  • The architecture validation relies on a hardcoded whitelist in VALID_ARCHITECTURES; consider centralizing this list in a shared config or deriving it from an authoritative source (e.g., rpm/OS metadata) so new or uncommon architectures don’t start causing unexpected validation failures at runtime.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The architecture validation relies on a hardcoded whitelist in `VALID_ARCHITECTURES`; consider centralizing this list in a shared config or deriving it from an authoritative source (e.g., rpm/OS metadata) so new or uncommon architectures don’t start causing unexpected validation failures at runtime.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@pindo696
pindo696 force-pushed the repo-sanitization-checks branch from c0c9b32 to 22509f4 Compare July 20, 2026 14:53
@pindo696
pindo696 marked this pull request as ready for review July 20, 2026 14:57

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Hey - I've left some high level feedback:

  • The new architecture validation relies on VALID_ARCHITECTURES being initialized via init_validator_architectures; consider enforcing or asserting this initialization (or providing a safe fallback) before PrimaryMD, UpdateInfoMD, and RepositoryController start validating arches to avoid unexpected Unknown architecture errors in production.
  • In _parse_update the code assumes <references> is always present (references.findall), which will raise if the element is missing; adding a None guard there would make updateinfo parsing more robust against slightly malformed metadata.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The new architecture validation relies on `VALID_ARCHITECTURES` being initialized via `init_validator_architectures`; consider enforcing or asserting this initialization (or providing a safe fallback) before `PrimaryMD`, `UpdateInfoMD`, and `RepositoryController` start validating arches to avoid unexpected `Unknown architecture` errors in production.
- In `_parse_update` the code assumes `<references>` is always present (`references.findall`), which will raise if the element is missing; adding a `None` guard there would make updateinfo parsing more robust against slightly malformed metadata.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

def _validate(self, value, field_type):
"""Validate a field and track metrics on failure."""
try:
return validate_field(value, field_type)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It lookups the validator function every single time for millions of items, the performace hit will add up

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

However it might be negligible

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The dict lookup is O(1), which is essentially free. So yes, its negligible. The real performance hit is inside each validator (regex matching or stripping,..)
I applied one more improvement by using .isdigit() instead of regex digit which should be faster.
Furthermore, implemented kind of cache for already seen validator values per field type defined, that turns most calls into a single set lookup, bypassing regex after the first occurrence in a tradeoff with memory.

@@ -61,21 +63,10 @@ def list_repositories(self):
return repos

def _import_basearch(self, basearch):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Perhaps it could be removed/refactored, since it's not doing any import anymore.

pindo696 added 5 commits July 28, 2026 10:29
Little sanitization for repo files during parsing process. Supporting test files taken and modified from vmaas-data repository. Part of RHINENG-13437
Grafana metrics to keep track of potential sanitization failures at the begginning. Also added REGISTRY property so worker metrics can be exposed upon update withount preinitialization.
Verify basearch field has one of allowed arch values. Part of RHINENG-13437
Instead of numeric counters reuse an existing vmaas reposcan errors plot to display validation failures.
Use a single source of truth for arch names based on database values. As we sanitize the archnames, the insert is no longer relevant to us.
@pindo696
pindo696 force-pushed the repo-sanitization-checks branch 2 times, most recently from 4a6d0bb to fd3409a Compare July 28, 2026 08:43
Bypass regex validation by caching already validated values to improve the validator performance. Replace digit regex for python idigit which should perform better as well.
@pindo696
pindo696 force-pushed the repo-sanitization-checks branch from fd3409a to 3b170d3 Compare July 28, 2026 09:08
Arch is not a valid arch value for validation. We need valid arch so import repos can be tested, otherwise the sanitization will reject it.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants