netchecks icon indicating copy to clipboard operation
netchecks copied to clipboard

Switch to Rust CEL implementation

Open hardbyte opened this issue 2 months ago • 3 comments

This PR upgrades the project's core dependencies, migrating from Pydantic v1 to v2 and switching from the Python celpy CEL library to the Rust-based common-expression-language library. This modernizes the dependency stack and improves performance for CEL expression evaluation.

Changes

  1. CEL Library Migration
  • Switched from Python celpy to Rust common-expression-language (v0.5.3)
    • Provides better performance for CEL expression evaluation
    • Required changes to how dict subclasses are handled in CEL contexts
    • Updated netcheck/validation.py with new API (cel.Context and cel.evaluate)
  1. Pydantic 2.x Migration
  • Upgraded operator from Pydantic v1 to v2
    • Replaced BaseSettings.Config inner class with SettingsConfigDict
    • Migrated custom settings source from function to PydanticBaseSettingsSource class
    • Updated operator/netchecks_operator/config.py to use new Pydantic 2.x patterns
    • Changed customise_sources to settings_customise_sources classmethod
  1. Context Loading Fix
  • Fixed LazyFileLoadingDict compatibility with Rust CEL
    • Added materialize() method to convert dict subclass to regular dict
    • Updated netcheck/runner.py to materialize directory contexts before CEL evaluation
    • Root cause: Rust CEL doesn't use Python's getitem protocol for dict subclasses
    • Fixes regression where directory-based contexts returned "None" instead of file contents
  1. Security Improvements
  • Added path traversal protection to LazyFileLoadingDict
    • Multiple layers of validation to prevent directory traversal attacks
    • Checks for path separators and relative paths in keys
    • Verifies resolved paths stay within intended directory using os.path.realpath()
  1. Test Coverage Improvements
  • Created tests/test_context.py with 12 comprehensive tests:
    • Lazy loading behavior and caching
    • Materialize functionality
    • CEL compatibility
    • Path traversal security
    • Edge cases (empty directories, subdirectories, nonexistent keys)
  • Created operator/tests/test_config.py with 11 comprehensive tests:
    • JSON config file loading via environment variable
    • Nested configuration objects
    • Pydantic settings source priority
    • Error handling (invalid JSON, missing files)
    • Default values and model configuration
  1. Dependency Updates
  • CLI dependencies (uv):
    • common-expression-language 0.5.3 (new, replaces celpy)
    • Updated pyyaml, typer, rich, and other dependencies to latest versions
  • Operator dependencies (poetry):
    • pydantic ^2.0
    • pydantic-settings ^2.0
    • kopf ^1.38.0
    • kubernetes ^34.0
    • Updated all dependencies to latest compatible versions
  1. Documentation
  • Added AGENTS.md with comprehensive project overview:
    • Architecture documentation for CLI and Operator
    • Development setup instructions
    • Testing philosophy and examples
    • CEL validation examples

Breaking Changes

None - all changes are internal implementation details. The external API remains unchanged.

Testing

All tests passing:

  • ✅ CLI tests: 24/24 passing
  • ✅ LazyFileLoadingDict tests: 12/12 passing
  • ✅ Operator config tests: 11/11 passing

Critical regression test test_run_test_with_external_dir_context now passes, verifying directory-based context loading works correctly with the new CEL library.

Migration Notes

  • The Rust CEL library behavior is largely compatible with the Python celpy library
  • Custom CEL functions (parse_json, parse_yaml, b64decode, b64encode) continue to work identically
  • Context loading from files, inline data, and directories works as before

Related Issues

  • Created upstream issue https://github.com/hardbyte/python-common-expression-language/issues/22 requesting native support for dict subclasses

hardbyte avatar Oct 14 '25 05:10 hardbyte

Pull Request Test Coverage Report for Build 18539798968

Details

  • 24 of 28 (85.71%) changed or added relevant lines in 3 files are covered.
  • No unchanged relevant lines lost coverage.
  • Overall coverage increased (+0.6%) to 92.151%

Changes Missing Coverage Covered Lines Changed/Added Lines %
netcheck/context.py 9 13 69.23%
<!-- Total: 24 28
Totals Coverage Status
Change from base Build 18457862351: 0.6%
Covered Lines: 317
Relevant Lines: 344

💛 - Coveralls

coveralls avatar Oct 14 '25 05:10 coveralls

Deploying netchecks-docs with  Cloudflare Pages  Cloudflare Pages

Latest commit: 6fcf736
Status: ✅  Deploy successful!
Preview URL: https://15c433bb.netchecks-docs.pages.dev
Branch Preview URL: https://switch-to-rust-cel-implement.netchecks-docs.pages.dev

View logs

/test

hardbyte avatar Oct 14 '25 06:10 hardbyte