{Compute} Add image deprecation status validation#32688
{Compute} Add image deprecation status validation#32688william051200 wants to merge 8 commits intoAzure:devfrom
Conversation
️✔️AzureCLI-FullTest
|
|
Hi @william051200, |
️✔️AzureCLI-BreakingChangeTest
|
|
Thank you for your contribution! We will review the pull request and get back to you soon. |
|
The git hooks are available for azure-cli and azure-cli-extensions repos. They could help you run required checks before creating the PR. Please sync the latest code with latest dev branch (for azure-cli) or main branch (for azure-cli-extensions). pip install azdev --upgrade
azdev setup -c <your azure-cli repo path> -r <your azure-cli-extensions repo path>
|
There was a problem hiding this comment.
Pull request overview
This PR adds image deprecation status validation for az vm create and az vmss create commands to warn users when they attempt to use images marked as "ScheduledForDeprecation". This addresses security and compliance risks associated with deprecated images, particularly critical for the Windows Server 2022 .NET 6 deprecation scenario.
Changes:
- Added a new validation function
_validate_image_deprecation_statusthat checks if a marketplace image is scheduled for deprecation - Integrated the validation into the
_validate_vm_create_storage_profilefunction to warn users during VM/VMSS creation - The validation queries the image deprecation status via Azure API and displays a warning when the status is "ScheduledForDeprecation"
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| def _validate_image_deprecation_status(cmd, namespace): | ||
| from .aaz.latest.vm.image import Show as _ImageShow | ||
| from ._actions import _get_latest_image_version | ||
|
|
||
| if namespace.os_version.lower() == 'latest': | ||
| latest_version = _get_latest_image_version( | ||
| cmd.cli_ctx, | ||
| location=namespace.location, | ||
| publisher=namespace.os_publisher, | ||
| offer=namespace.os_offer, | ||
| sku=namespace.os_sku, | ||
| ) | ||
| else: | ||
| latest_version = namespace.os_version | ||
|
|
||
| image = _ImageShow(cli_ctx=cmd.cli_ctx)(command_args={ | ||
| 'location': namespace.location, | ||
| 'publisher': namespace.os_publisher, | ||
| 'offer': namespace.os_offer, | ||
| 'sku': namespace.os_sku, | ||
| 'version': latest_version, | ||
| }) | ||
|
|
||
| if not image: | ||
| return | ||
|
|
||
| if image.get('imageDeprecationStatus', {}).get('imageState') == 'ScheduledForDeprecation': | ||
| logger.warning('The selected image is scheduled for deprecation.') |
There was a problem hiding this comment.
The function assumes that namespace has os_version, os_publisher, os_offer, and os_sku attributes, but these are only populated when the image is specified as a URN (publisher:offer:sku:version) or URN alias. For other image types like managed custom images, shared gallery images, community gallery images, or VHD URIs, these attributes won't exist and will cause an AttributeError. Add a guard check at the beginning of the function to return early if these attributes don't exist.
| }) | ||
|
|
||
| if not image: | ||
| return |
There was a problem hiding this comment.
Remove the trailing space at the end of the return statement.
| return | |
| return |
| image = _ImageShow(cli_ctx=cmd.cli_ctx)(command_args={ | ||
| 'location': namespace.location, | ||
| 'publisher': namespace.os_publisher, | ||
| 'offer': namespace.os_offer, | ||
| 'sku': namespace.os_sku, | ||
| 'version': latest_version, | ||
| }) | ||
|
|
||
| if not image: | ||
| return | ||
|
|
There was a problem hiding this comment.
The API call to _ImageShow could potentially fail (e.g., network issues, invalid parameters, image not found). While there's a check for empty response, there's no try-except block to handle potential exceptions. Consider wrapping the API calls in a try-except block to gracefully handle errors and avoid crashing the validation process.
| image = _ImageShow(cli_ctx=cmd.cli_ctx)(command_args={ | |
| 'location': namespace.location, | |
| 'publisher': namespace.os_publisher, | |
| 'offer': namespace.os_offer, | |
| 'sku': namespace.os_sku, | |
| 'version': latest_version, | |
| }) | |
| if not image: | |
| return | |
| try: | |
| image = _ImageShow(cli_ctx=cmd.cli_ctx)(command_args={ | |
| 'location': namespace.location, | |
| 'publisher': namespace.os_publisher, | |
| 'offer': namespace.os_offer, | |
| 'sku': namespace.os_sku, | |
| 'version': latest_version, | |
| }) | |
| except Exception as err: # pylint: disable=broad-except | |
| logger.warning('Failed to retrieve image deprecation status: %s', err) | |
| return | |
| if not image: | |
| return |
| def _validate_image_deprecation_status(cmd, namespace): | ||
| from .aaz.latest.vm.image import Show as _ImageShow | ||
| from ._actions import _get_latest_image_version | ||
|
|
||
| if namespace.os_version.lower() == 'latest': | ||
| latest_version = _get_latest_image_version( | ||
| cmd.cli_ctx, | ||
| location=namespace.location, | ||
| publisher=namespace.os_publisher, | ||
| offer=namespace.os_offer, | ||
| sku=namespace.os_sku, | ||
| ) | ||
| else: | ||
| latest_version = namespace.os_version | ||
|
|
||
| image = _ImageShow(cli_ctx=cmd.cli_ctx)(command_args={ | ||
| 'location': namespace.location, | ||
| 'publisher': namespace.os_publisher, | ||
| 'offer': namespace.os_offer, | ||
| 'sku': namespace.os_sku, | ||
| 'version': latest_version, | ||
| }) | ||
|
|
||
| if not image: | ||
| return | ||
|
|
||
| if image.get('imageDeprecationStatus', {}).get('imageState') == 'ScheduledForDeprecation': | ||
| logger.warning('The selected image is scheduled for deprecation.') |
There was a problem hiding this comment.
The new validation function _validate_image_deprecation_status lacks test coverage. Similar validation functions in this module have corresponding tests in test_vm_defaults.py (e.g., test_vm_validator_retrieve_image_info_cross_subscription). Consider adding test coverage for this new deprecation status validation to ensure it works correctly for both 'latest' version and specific version scenarios.
|
|
||
| def _validate_image_deprecation_status(cmd, namespace): | ||
| from .aaz.latest.vm.image import Show as _ImageShow | ||
| from ._actions import _get_latest_image_version |
There was a problem hiding this comment.
The import of _get_latest_image_version from ._actions is redundant as it's already imported at the module level (line 27). Remove this duplicate import.
| from ._actions import _get_latest_image_version |
Related command
az vm createaz vmss createDescription
Resolve #32682
Warning displayed when image is marked as "scheduledfordeprecation":

Testing Guide
History Notes
This checklist is used to make sure that common guidelines for a pull request are followed.
The PR title and description has followed the guideline in Submitting Pull Requests.
I adhere to the Command Guidelines.
I adhere to the Error Handling Guidelines.