Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat(pyavd): Return deprecation warnings on validations #3238

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions python-avd/pyavd/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@
""" Library for running Arista Validated Designs (AVD) in Python
"""

PYAVD_PRERELEASE = "b1" # Set this to aN or bN for alpha and beta releases of pyavd itself. Empty string when pyavd is released.
PYAVD_PRERELEASE = "b2" # Set this to aN or bN for alpha and beta releases of pyavd itself. Empty string when pyavd is released.

__author__ = "Arista Networks"
__copyright__ = "Copyright 2023 Arista Networks"
__license__ = "Apache 2.0"
__version__ = "4.4.0b1"
__version__ = "4.4.0b2"

__all__ = [
"get_avd_facts",
Expand Down
28 changes: 21 additions & 7 deletions python-avd/pyavd/avd_schema_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@
from .vendor.errors import AvdConversionWarning, AvdDeprecationWarning, AvdValidationError
from .vendor.schema.avdschema import AvdSchema

IGNORE_EXCEPTIONS = (AvdDeprecationWarning, AvdConversionWarning)
RETURN_EXCEPTIONS = AvdValidationError
IGNORE_EXCEPTIONS = AvdConversionWarning
VALIDATION_ERROR_EXCEPTIONS = AvdValidationError
DEPRECATION_WARNING_EXCEPTIONS = AvdDeprecationWarning


class AvdSchemaTools:
Expand All @@ -27,27 +28,36 @@ def __init__(self, schema: dict = None, schema_id: str = None) -> None:
"""
self.avdschema = AvdSchema(schema=schema, schema_id=schema_id)

def convert_data(self, data: dict) -> None:
def convert_data(self, data: dict) -> list[AvdDeprecationWarning]:
"""
Convert data according to the schema (convert_types)
The data conversion is done in-place (updating the original "data" dict).

Args:
data:
Input variables which should be converted according to the schema.

Returns:
List of AvdDeprecationWarnings
"""

# avdschema.convert returns a Generator, so we have to iterate through it to perform the actual conversions.
exceptions: Generator = self.avdschema.convert(data)

result = []
for exception in exceptions:
# Ignore conversions and deprecations
if isinstance(exception, IGNORE_EXCEPTIONS):
continue

if isinstance(exception, DEPRECATION_WARNING_EXCEPTIONS):
result.append(exception)
continue

if isinstance(exception, Exception):
raise exception

return None
return result

def validate_data(self, data: dict) -> ValidationResult:
"""
Expand All @@ -58,9 +68,9 @@ def validate_data(self, data: dict) -> ValidationResult:
Input variables which are to be validated according to the schema.

Returns:
Instance of ValidationResult, where "failed" is True if data is invalid and "errors" is a list of AvdValidationError.
Validation result object with any validation errors or deprecation warnings.
"""
result = ValidationResult(failed=False, validation_errors=[])
result = ValidationResult(failed=False)

# avdschema.validate returns a Generator, so we have to iterate through it to perform the actual validations.
exceptions: Generator = self.avdschema.validate(data)
Expand All @@ -69,11 +79,15 @@ def validate_data(self, data: dict) -> ValidationResult:
if isinstance(exception, IGNORE_EXCEPTIONS):
continue

if isinstance(exception, RETURN_EXCEPTIONS):
if isinstance(exception, VALIDATION_ERROR_EXCEPTIONS):
result.validation_errors.append(exception)
result.failed = True
continue

if isinstance(exception, DEPRECATION_WARNING_EXCEPTIONS):
result.deprecation_warnings.append(exception)
continue

if isinstance(exception, Exception):
raise exception

Expand Down
9 changes: 5 additions & 4 deletions python-avd/pyavd/validate_inputs.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@ def validate_inputs(inputs: dict) -> ValidationResult:
inputs: Dictionary with inputs for "eos_designs".

Returns:
Instance of ValidationResult, where "failed" is True if data is not valid according to the schema
and "errors" is a list of AvdValidationErrors containing schema violations.
Validation result object with any validation errors or deprecation warnings.
"""

# Initialize a global instance of eos_designs_schema_tools
Expand All @@ -38,7 +37,9 @@ def validate_inputs(inputs: dict) -> ValidationResult:
inputs.setdefault("network_services_keys", shared_utils.network_services_keys)

# Inplace conversion of data
eos_designs_schema_tools.convert_data(inputs)
deprecation_warnings = eos_designs_schema_tools.convert_data(inputs)

# Validate input data
return eos_designs_schema_tools.validate_data(inputs)
validation_result = eos_designs_schema_tools.validate_data(inputs)
validation_result.deprecation_warnings.extend(deprecation_warnings)
return validation_result
9 changes: 5 additions & 4 deletions python-avd/pyavd/validate_structured_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@ def validate_structured_config(structured_config: dict) -> ValidationResult:
structured_config: Dictionary with structured configuration.

Returns:
Instance of ValidationResult, where "failed" is True if data is not valid according to the schema
and "errors" is a list of AvdValidationErrors containing schema violations.
Validation result object with any validation errors or deprecation warnings.
"""

# Initialize a global instance of eos_cli_config_gen_schema_tools
Expand All @@ -28,7 +27,9 @@ def validate_structured_config(structured_config: dict) -> ValidationResult:
eos_cli_config_gen_schema_tools = AvdSchemaTools(schema_id=EOS_CLI_CONFIG_GEN_SCHEMA_ID)

# Inplace conversion of data
eos_cli_config_gen_schema_tools.convert_data(structured_config)
deprecation_warnings = eos_cli_config_gen_schema_tools.convert_data(structured_config)

# Validate input data
return eos_cli_config_gen_schema_tools.validate_data(structured_config)
validation_result = eos_cli_config_gen_schema_tools.validate_data(structured_config)
validation_result.deprecation_warnings.extend(deprecation_warnings)
return validation_result
9 changes: 6 additions & 3 deletions python-avd/pyavd/validation_result.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Copyright (c) 2023 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
from .vendor.errors import AvdValidationError
from .vendor.errors import AvdDeprecationWarning, AvdValidationError


class ValidationResult:
Expand All @@ -11,11 +11,14 @@ class ValidationResult:
Attributes:
failed: True if data is not valid according to the schema. Otherwise False.
validation_errors: List of AvdValidationErrors containing schema violations.
deprecation_warnings: List of AvdDeprecationWarnings containing warning for deprecated inputs.
"""

failed: bool
validation_errors: list[AvdValidationError]
deprecation_warnings: list[AvdDeprecationWarning]

def __init__(self, failed: bool, validation_errors: list):
def __init__(self, failed: bool, validation_errors: list = None, deprecation_warnings: list = None):
self.failed = failed
self.validation_errors = validation_errors
self.validation_errors = validation_errors or []
self.deprecation_warnings = deprecation_warnings or []