Skip to content

feat(cli): support legacy validators in ado upgrade#629

Open
AlessandroPomponio wants to merge 57 commits intomainfrom
ap_622_legacy_validator
Open

feat(cli): support legacy validators in ado upgrade#629
AlessandroPomponio wants to merge 57 commits intomainfrom
ap_622_legacy_validator

Conversation

@AlessandroPomponio
Copy link
Copy Markdown
Member

@AlessandroPomponio AlessandroPomponio commented Feb 27, 2026

Summary

This pull request implements a comprehensive legacy validator system for handling deprecated resource formats in the ADO orchestrator. The system allows users to upgrade resources that contain deprecated fields by applying legacy validators through the CLI, with features including automatic dependency resolution, transaction safety, and helpful error messages.

Files Changed

Core Legacy System

📄 orchestrator/core/legacy/__init__.py

Exports the main components of the legacy validator system: LegacyValidatorMetadata, LegacyValidatorRegistry, and the legacy_validator decorator.

📄 orchestrator/core/legacy/metadata.py

Defines the LegacyValidatorMetadata model that stores information about legacy validators including identifier, resource type, deprecated field paths, version information, dependencies, and the validator function itself. Includes a format_info() method for displaying validator information.

📄 orchestrator/core/legacy/registry.py

Implements the LegacyValidatorRegistry class that manages registration and retrieval of legacy validators. Includes methods for finding validators by resource type or deprecated field paths, and a topological sort algorithm for resolving validator dependencies. Also provides the @legacy_validator decorator for registering validators.

📄 orchestrator/core/legacy/utils.py

Provides utility functions for working with nested dictionary structures: get_parent_dict_and_key(), get_nested_value(), set_nested_value(), remove_nested_field(), and has_nested_field(). These helpers simplify field manipulation in validators.

Legacy Validators

📄 orchestrator/core/legacy/validators/__init__.py

Imports all validator subpackages to trigger their registration when the module is loaded.

📄 orchestrator/core/legacy/validators/discoveryspace/__init__.py

Exports discovery space validators.

📄 orchestrator/core/legacy/validators/discoveryspace/entitysource_to_samplestore.py

Validator that renames entitySourceIdentifier to sampleStoreIdentifier in discovery space configurations (deprecated in v0.9.6, removed in v1.0.0).

📄 orchestrator/core/legacy/validators/discoveryspace/properties_field_removal.py

Validator that removes the deprecated properties field from discovery space configurations (deprecated in v0.10.1, removed in v1.0.0).

📄 orchestrator/core/legacy/validators/operation/__init__.py

Exports operation validators.

📄 orchestrator/core/legacy/validators/operation/actuators_field_removal.py

Validator that removes the deprecated actuators field from operation configurations (deprecated in v0.9.6, removed in v1.0.0).

📄 orchestrator/core/legacy/validators/operation/randomwalk_mode_to_sampler_config.py

Validator that migrates random_walk parameters from flat structure to nested samplerConfig (deprecated in v1.0.1, removed in v1.2).

📄 orchestrator/core/legacy/validators/resource/__init__.py

Exports generic resource validators.

📄 orchestrator/core/legacy/validators/resource/entitysource_to_samplestore.py

Validator that converts resource kind from 'entitysource' to 'samplestore' with dependencies on module type, class, and name validators (deprecated in v0.9.6, removed in v1.0.0).

📄 orchestrator/core/legacy/validators/samplestore/__init__.py

Exports sample store validators.

📄 orchestrator/core/legacy/validators/samplestore/entitysource_migrations.py

Contains four validators for migrating entitysource naming to samplestore: module type, module class, module name, and removing deprecated storage location (all deprecated in v0.9.6, removed in v1.0.0).

📄 orchestrator/core/legacy/validators/samplestore/gt4sd_transformer_migration.py

Validator that converts GT4SDTransformer plugin usage to CSVSampleStore with explicit parameters (deprecated in v1.3.5, removed in v1.6.0).

📄 orchestrator/core/legacy/validators/samplestore/v1_to_v2_csv_migration.py

Validator that migrates CSV sample stores from v1 format (constitutivePropertyColumns in config) to v2 format (per-experiment constitutivePropertyMap) (deprecated in v1.3.5, removed in v1.6.0).

CLI Components

📄 orchestrator/cli/commands/upgrade.py

Adds --apply-legacy-validator and --list-legacy-validators options to the upgrade command. Updates command documentation with examples of listing and applying legacy validators.

📄 orchestrator/cli/models/parameters.py

Adds apply_legacy_validator and list_legacy_validators fields to AdoUpgradeCommandParameters.

📄 orchestrator/cli/utils/legacy/__init__.py

Exports the list_legacy_validators() function.

📄 orchestrator/cli/utils/legacy/common.py

Provides common utilities for legacy validator handling: extract_deprecated_field_paths() extracts field paths from validation errors, and print_validator_suggestions_with_dependencies() displays validator suggestions with dependency information.

📄 orchestrator/cli/utils/legacy/list.py

Implements list_legacy_validators() function that displays all available legacy validators for a specific resource type.

📄 orchestrator/cli/utils/resources/handlers.py

Major update to handle_ado_upgrade() to support legacy validators with two-phase transaction safety (validate all resources before saving any). Adds _handle_upgrade_validation_error() helper that suggests applicable legacy validators when validation errors occur.

Core System Updates

📄 orchestrator/core/samplestore/config.py

Adds null checks for module name before loading module class or validating parameters/storage location to prevent errors during legacy validation.

📄 orchestrator/metastore/base.py

Adds validation to check for required nested keys in sample store resource dictionaries with helpful error messages.

📄 orchestrator/metastore/sql/statements.py

Fixes resource upsert to use .value when accessing the kind enum.

Tests

📄 tests/conftest.py

Adds three test fixtures: session_legacy_validators (loads validators once per session), isolated_legacy_validator_registry (isolates registry for each test), and legacy_validators_loaded (ensures validators are loaded and isolated).

📄 tests/core/legacy/validators/samplestore/test_gt4sd_transformer_migration.py

Comprehensive tests for the GT4SDTransformer migration validator covering various scenarios including existing parameters, multiple copyFrom entries, and missing fields.

📄 tests/core/test_legacy_registry.py

Unit tests for the legacy validator registry including registration, retrieval, field path matching, and the decorator functionality.

📄 tests/core/test_legacy_utils.py

Tests for all legacy validator utility functions covering nested dictionary operations.

📄 tests/core/test_legacy_validators.py

Integration tests for legacy validators with pydantic models and the upgrade process, including chained validators and CLI integration.

📄 tests/core/test_upgrade_transaction_safety.py

Tests for Phase 1 transaction safety ensuring all resources are validated before any are saved, and validation failures prevent all saves.

📄 tests/core/test_validator_dependencies.py

Tests for validator dependency resolution covering no dependencies, simple chains, diamond patterns, circular dependencies, missing dependencies, and multiple roots.

@DRL-NextGen
Copy link
Copy Markdown
Member

DRL-NextGen commented Mar 23, 2026

Checks Summary

Last run: 2026-03-27T09:50:16.353Z

Mend Unified Agent vulnerability scan found 2 vulnerabilities:

Severity Identifier Package Details Fix
🔷 Medium CVE-2026-25645 requests-2.32.5-py3-none-any.whl
Requests is a HTTP library. Prior to version 2.33.0, the "requests.utils.extract_zipped_paths()" uti...Requests is a HTTP library. Prior to version 2.33.0, the "requests.utils.extract_zipped_paths()" utility function uses a predictable filename when extracting files from zip archives into the system temporary directory. If the target file already exists, it is reused without validation. A local attacker with write access to the temp directory could pre-create a malicious file that would be loaded in place of the legitimate one. Standard usage of the Requests library is not affected by this vulnerability. Only applications that call "extract_zipped_paths()" directly are impacted. Starting in version 2.33.0, the library extracts files to a non-deterministic location. If developers are unable to upgrade, they can set "TMPDIR" in their environment to a directory with restricted write access.
Upgrade to version https://github.com/psf/requests.git - v2.33.0
🔸 Low CVE-2026-4539 pygments-2.19.2-py3-none-any.whl
A security flaw has been discovered in pygments up to 2.19.2. The impacted element is the function A...A security flaw has been discovered in pygments up to 2.19.2. The impacted element is the function AdlLexer of the file pygments/lexers/archetype.py. The manipulation results in inefficient regular expression complexity. The attack is only possible with local access. The exploit has been released to the public and may be used for attacks. The project was informed of the problem early through an issue report but has not responded yet.
Not Available

Made with Bob

Signed-off-by: Alessandro Pomponio <alessandro.pomponio1@ibm.com>
Signed-off-by: Alessandro Pomponio <alessandro.pomponio1@ibm.com>
Signed-off-by: Alessandro Pomponio <alessandro.pomponio1@ibm.com>
Signed-off-by: Alessandro Pomponio <alessandro.pomponio1@ibm.com>
Signed-off-by: Alessandro Pomponio <alessandro.pomponio1@ibm.com>
Signed-off-by: Alessandro Pomponio <alessandro.pomponio1@ibm.com>
Signed-off-by: Alessandro Pomponio <alessandro.pomponio1@ibm.com>
Signed-off-by: Alessandro Pomponio <alessandro.pomponio1@ibm.com>
Signed-off-by: Alessandro Pomponio <alessandro.pomponio1@ibm.com>
Signed-off-by: Alessandro Pomponio <alessandro.pomponio1@ibm.com>
Signed-off-by: Alessandro Pomponio <alessandro.pomponio1@ibm.com>
Signed-off-by: Alessandro Pomponio <alessandro.pomponio1@ibm.com>
Signed-off-by: Alessandro Pomponio <alessandro.pomponio1@ibm.com>
Signed-off-by: Alessandro Pomponio <alessandro.pomponio1@ibm.com>
Signed-off-by: Alessandro Pomponio <alessandro.pomponio1@ibm.com>
Signed-off-by: Alessandro Pomponio <alessandro.pomponio1@ibm.com>
Signed-off-by: Alessandro Pomponio <alessandro.pomponio1@ibm.com>
For safer updates

Signed-off-by: Alessandro Pomponio <alessandro.pomponio1@ibm.com>
Signed-off-by: Alessandro Pomponio <alessandro.pomponio1@ibm.com>
Signed-off-by: Alessandro Pomponio <alessandro.pomponio1@ibm.com>
Signed-off-by: Alessandro Pomponio <alessandro.pomponio1@ibm.com>
Signed-off-by: Alessandro Pomponio <alessandro.pomponio1@ibm.com>
Signed-off-by: Alessandro Pomponio <alessandro.pomponio1@ibm.com>
Signed-off-by: Alessandro Pomponio <alessandro.pomponio1@ibm.com>
Signed-off-by: Alessandro Pomponio <alessandro.pomponio1@ibm.com>
Signed-off-by: Alessandro Pomponio <alessandro.pomponio1@ibm.com>
…lidator registry

Signed-off-by: Alessandro Pomponio <alessandro.pomponio1@ibm.com>
AlessandroPomponio and others added 18 commits March 25, 2026 14:03
Signed-off-by: Alessandro Pomponio <alessandro.pomponio1@ibm.com>
Signed-off-by: Alessandro Pomponio <alessandro.pomponio1@ibm.com>
Signed-off-by: Alessandro Pomponio <alessandro.pomponio1@ibm.com>
We don't match on leaf nodes anymore

Signed-off-by: Alessandro Pomponio <alessandro.pomponio1@ibm.com>
Signed-off-by: Alessandro Pomponio <alessandro.pomponio1@ibm.com>
Signed-off-by: Alessandro Pomponio <alessandro.pomponio1@ibm.com>
Signed-off-by: Alessandro Pomponio <alessandro.pomponio1@ibm.com>
Signed-off-by: Alessandro Pomponio <alessandro.pomponio1@ibm.com>
Signed-off-by: Alessandro Pomponio <alessandro.pomponio1@ibm.com>
Signed-off-by: Alessandro Pomponio <alessandro.pomponio1@ibm.com>
Signed-off-by: Alessandro Pomponio <alessandro.pomponio1@ibm.com>
Signed-off-by: Alessandro Pomponio <alessandro.pomponio1@ibm.com>
Signed-off-by: Alessandro Pomponio <alessandro.pomponio1@ibm.com>
Signed-off-by: Alessandro Pomponio <alessandro.pomponio1@ibm.com>
Signed-off-by: Alessandro Pomponio <alessandro.pomponio1@ibm.com>
Signed-off-by: Alessandro Pomponio <alessandro.pomponio1@ibm.com>
…oaded

Signed-off-by: Alessandro Pomponio <alessandro.pomponio1@ibm.com>
Signed-off-by: Alessandro Pomponio <alessandro.pomponio1@ibm.com>
@AlessandroPomponio
Copy link
Copy Markdown
Member Author

Example of this in action:

(ado-core) alessandropomponio@MacBook-Pro-di-Alessandro ~/D/G/p/ado (ap_622_legacy_validator) [1]> ado upgrade space

Validation Error while upgrading discoveryspace resources

Some resources could not be loaded due to validation errors.

Fields with validation errors: 2 field(s)

Error details:
  • config.entitySourceIdentifier:
    - Extra inputs are not permitted (got: 04b473)
  • config.properties:
    - Extra inputs are not permitted (got: {'stochastic': False})
INFO:   The following validator(s) are a match:

  1. discoveryspace_entitysource_to_samplestore
     Renames 'entitySourceIdentifier' to 'sampleStoreIdentifier' in discovery space configurations
     Handles: config.entitySourceIdentifier

  2. discoveryspace_properties_field_removal
     Removes the deprecated 'properties' field from discovery space configurations
     Handles: config.properties

HINT:   To attempt the upgrade using the suggested legacy validator(s) run:
        ado upgrade discoveryspace --apply-legacy-validator discoveryspace_entitysource_to_samplestore --apply-legacy-validator discoveryspace_properties_field_removal

HINT:   To list all legacy validators run:
        ado upgrade discoveryspace --list-legacy-validators

(ado-core) alessandropomponio@MacBook-Pro-di-Alessandro ~/D/G/p/ado (ap_622_legacy_validator) [1]> ado upgrade discoveryspace --apply-legacy-validator discoveryspace_entitysource_to_samplestore --apply-legacy-validator discoveryspace_properties_field_removal

Success! 

Signed-off-by: Alessandro Pomponio <alessandro.pomponio1@ibm.com>
Copy link
Copy Markdown
Member

@michael-johnston michael-johnston left a comment

Choose a reason for hiding this comment

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

So to summarise what the proposed protocol/plan is going forward, I get that

  • we change a resource so we add an upgrade validator for some amount of time
  • at end of that time we remove the upgrade validator from the model but keep it somewhere else (core/legacy)
  • then if someone didn't upgrade in time the legacy validator is there.

This does beg the question if we should take on the burden of having the legacy code which is ever growing - which was something we didn't want? (some of the ones above are pre open-sourcing).

On the implementation as is I think the term validator is not quite right - they are "upgraders" or "migrators". It also took me a few reads to understand what the message was telling me - which probably means we can improve it a bit.

I've taken a stab below - I realise not all changes may be possible due to using pydantic error strings. I'm just trialling the term "migrator" also.


Validation Error while upgrading discoveryspace resources

Some resources could not be upgraded as their stored representation is too old

The problematic fields are: 2 field(s)

  • config.entitySourceIdentifier:
    - Error: Extra inputs are not permitted (got: 04b473)
  • config.properties:
    - Error: Extra inputs are not permitted (got: {'stochastic': False})

INFO:   The following legacy migrators(s) address these fields and you may be able to use the to remove the errors:

  1. discoveryspace_entitysource_to_samplestore
     Renames 'entitySourceIdentifier' to 'sampleStoreIdentifier' in discovery space configurations
     Handles: config.entitySourceIdentifier

  2. discoveryspace_properties_field_removal
     Removes the deprecated 'properties' field from discovery space configurations
     Handles: config.properties

HINT:   To attempt the upgrade using the suggested legacy migrator(s) run:
        ado upgrade discoveryspace --apply-legacy-migrator discoveryspace_entitysource_to_samplestore --apply-legacy-migrator discoveryspace_properties_field_removal

HINT:   To list all legacy migrators run:
        ado upgrade discoveryspace --list-legacy-migrator

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.

feat(cli): allow for extended legacy support for ado upgrade of resources feat(core): introduce a legacy validator registry system

3 participants