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

[Compute] az sig image-version create/update: Add new parameter --block-deletion-before-end-of-life to support blocking deletion if the end of life has not expired #31013

Open
wants to merge 4 commits into
base: dev
Choose a base branch
from
Open
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
2 changes: 1 addition & 1 deletion src/azure-cli-core/azure/cli/core/profiles/_shared.py
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ def default_api_version(self):
'snapshots': '2023-10-02',
'galleries': '2021-10-01',
'gallery_images': '2021-10-01',
'gallery_image_versions': '2023-07-03',
'gallery_image_versions': '2024-03-03',
'gallery_applications': '2021-07-01',
'gallery_application_versions': '2022-01-03',
'shared_galleries': '2022-01-03',
Expand Down
3 changes: 3 additions & 0 deletions src/azure-cli/azure/cli/command_modules/vm/_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -1378,6 +1378,9 @@ def load_arguments(self, _):
help='Space-separated list of regions, edge zones, replica counts and storage types. Use `<region>=<edge zone>[=<replica count>][=<storage account type>]` to optionally set the replica count and/or storage account type for each region. '
'If a replica count is not specified, the default replica count will be used. If a storage account type is not specified, the default storage account type will be used. '
'If "--target-edge-zones None" is specified, the target extended locations will be cleared.')
c.argument('block_deletion_before_end_of_life', arg_type=get_three_state_flag(), min_api='2024-03-03',
options_list=['--block-deletion-before-end-of-life', '--block-deletion'],
help="Indicates whether or not the deletion is blocked for this gallery image version if its end of life has not expired")

for scope in ['sig image-version create', 'sig image-version update', 'sig image-version undelete']:
with self.argument_context(scope, operation_group='gallery_image_versions') as c:
Expand Down
31 changes: 21 additions & 10 deletions src/azure-cli/azure/cli/command_modules/vm/_validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -514,19 +514,30 @@ def _validate_vm_create_storage_profile(cmd, namespace, for_scale_set=False):
namespace.os_type = image_info.os_type
gallery_image_version = res.get('child_name_2', '')
if gallery_image_version.lower() in ['latest', '']:
image_version_infos = compute_client.gallery_image_versions.list_by_gallery_image(
resource_group_name=res['resource_group'], gallery_name=res['name'],
gallery_image_name=res['child_name_1'])
image_version_infos = [x for x in image_version_infos if not x.publishing_profile.exclude_from_latest]
from .aaz.latest.sig.image_version import List as _SigImageVersionList
image_version_infos = _SigImageVersionList(cli_ctx=cmd.cli_ctx)(command_args={
"resource_group": res['resource_group'],
"gallery_name": res['name'],
"gallery_image_definition": res['child_name_1']
})
image_version_infos = [x for x in image_version_infos
if not x.get("publishingProfile", {}).get("excludeFromLatest", None)]
if not image_version_infos:
raise CLIError('There is no latest image version exists for "{}"'.format(namespace.image))
image_version_info = sorted(image_version_infos, key=lambda x: x.publishing_profile.published_date)[-1]
image_version_info = sorted(image_version_infos,
key=lambda x: x["publishingProfile"]["publishedDate"])[-1]
image_data_disks = image_version_info.get("storageProfile", {}).get("dataDiskImages", [])
image_data_disks = [{'lun': disk["lun"]} for disk in image_data_disks]
else:
image_version_info = compute_client.gallery_image_versions.get(
resource_group_name=res['resource_group'], gallery_name=res['name'],
gallery_image_name=res['child_name_1'], gallery_image_version_name=res['child_name_2'])
image_data_disks = image_version_info.storage_profile.data_disk_images or []
image_data_disks = [{'lun': disk.lun} for disk in image_data_disks]
from .aaz.latest.sig.image_version import Show as _SigImageVersionShow
image_version_info = _SigImageVersionShow(cli_ctx=cmd.cli_ctx)(command_args={
"resource_group": res['resource_group'],
"gallery_name": res['name'],
"gallery_image_definition": res['child_name_1'],
"gallery_image_version_name": res['child_name_2'],
})
image_data_disks = image_version_info.get("storageProfile", {}).get("dataDiskImages", [])
image_data_disks = [{'lun': disk["lun"]} for disk in image_data_disks]

else:
raise CLIError('usage error: unrecognized image information "{}"'.format(namespace.image))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ class Create(AAZCommand):
"""

_aaz_info = {
"version": "2023-07-03",
"version": "2024-03-03",
"resources": [
["mgmt-plane", "/subscriptions/{}/resourcegroups/{}/providers/microsoft.compute/galleries/{}/images/{}/versions/{}", "2023-07-03"],
["mgmt-plane", "/subscriptions/{}/resourcegroups/{}/providers/microsoft.compute/galleries/{}/images/{}/versions/{}", "2024-03-03"],
]
}

Expand Down Expand Up @@ -86,6 +86,11 @@ def _build_arguments_schema(cls, *args, **kwargs):
arg_group="Properties",
help="The publishing profile of a gallery image Version.",
)
_args_schema.restore = AAZBoolArg(
options=["--restore"],
arg_group="Properties",
help="Indicates if this is a soft-delete resource restoration request.",
)
_args_schema.safety_profile = AAZObjectArg(
options=["--safety-profile"],
arg_group="Properties",
Expand Down Expand Up @@ -123,7 +128,7 @@ def _build_arguments_schema(cls, *args, **kwargs):
publishing_profile.storage_account_type = AAZStrArg(
options=["storage-account-type"],
help="Specifies the storage account type to be used to store the image. This property is not updatable.",
enum={"Premium_LRS": "Premium_LRS", "Standard_LRS": "Standard_LRS", "Standard_ZRS": "Standard_ZRS"},
enum={"PremiumV2_LRS": "PremiumV2_LRS", "Premium_LRS": "Premium_LRS", "Standard_LRS": "Standard_LRS", "Standard_ZRS": "Standard_ZRS"},
)
publishing_profile.target_extended_locations = AAZListArg(
options=["target-extended-locations"],
Expand Down Expand Up @@ -174,6 +179,10 @@ def _build_arguments_schema(cls, *args, **kwargs):
target_regions.Element = AAZObjectArg()

_element = cls._args_schema.publishing_profile.target_regions.Element
_element.additional_replica_sets = AAZListArg(
options=["additional-replica-sets"],
help="List of storage sku with replica count to create direct drive replicas.",
)
_element.encryption = AAZObjectArg(
options=["encryption"],
help="Optional. Allows users to provide customer managed keys for encrypting the OS and data disks in the gallery artifact.",
Expand All @@ -195,14 +204,32 @@ def _build_arguments_schema(cls, *args, **kwargs):
_element.storage_account_type = AAZStrArg(
options=["storage-account-type"],
help="Specifies the storage account type to be used to store the image. This property is not updatable.",
enum={"Premium_LRS": "Premium_LRS", "Standard_LRS": "Standard_LRS", "Standard_ZRS": "Standard_ZRS"},
enum={"PremiumV2_LRS": "PremiumV2_LRS", "Premium_LRS": "Premium_LRS", "Standard_LRS": "Standard_LRS", "Standard_ZRS": "Standard_ZRS"},
)

additional_replica_sets = cls._args_schema.publishing_profile.target_regions.Element.additional_replica_sets
additional_replica_sets.Element = AAZObjectArg()

_element = cls._args_schema.publishing_profile.target_regions.Element.additional_replica_sets.Element
_element.regional_replica_count = AAZIntArg(
options=["regional-replica-count"],
help="The number of direct drive replicas of the Image Version to be created.This Property is updatable",
)
_element.storage_account_type = AAZStrArg(
options=["storage-account-type"],
help="Specifies the storage account type to be used to create the direct drive replicas",
enum={"PremiumV2_LRS": "PremiumV2_LRS", "Premium_LRS": "Premium_LRS", "Standard_LRS": "Standard_LRS", "Standard_ZRS": "Standard_ZRS"},
)

safety_profile = cls._args_schema.safety_profile
safety_profile.allow_deletion_of_replicated_locations = AAZBoolArg(
options=["allow-deletion-of-replicated-locations"],
help="Indicates whether or not removing this Gallery Image Version from replicated regions is allowed.",
)
safety_profile.block_deletion_before_end_of_life = AAZBoolArg(
options=["block-deletion-before-end-of-life"],
help="Indicates whether or not the deletion is blocked for this Gallery Image Version if its End Of Life has not expired.",
)

security_profile = cls._args_schema.security_profile
security_profile.uefi_settings = AAZObjectArg(
Expand Down Expand Up @@ -522,7 +549,7 @@ def url_parameters(self):
def query_parameters(self):
parameters = {
**self.serialize_query_param(
"api-version", "2023-07-03",
"api-version", "2024-03-03",
required=True,
),
}
Expand Down Expand Up @@ -554,6 +581,7 @@ def content(self):
properties = _builder.get(".properties")
if properties is not None:
properties.set_prop("publishingProfile", AAZObjectType, ".publishing_profile")
properties.set_prop("restore", AAZBoolType, ".restore")
properties.set_prop("safetyProfile", AAZObjectType, ".safety_profile")
properties.set_prop("securityProfile", AAZObjectType, ".security_profile")
properties.set_prop("storageProfile", AAZObjectType, ".storage_profile", typ_kwargs={"flags": {"required": True}})
Expand Down Expand Up @@ -591,15 +619,26 @@ def content(self):

_elements = _builder.get(".properties.publishingProfile.targetRegions[]")
if _elements is not None:
_elements.set_prop("additionalReplicaSets", AAZListType, ".additional_replica_sets")
_CreateHelper._build_schema_encryption_images_create(_elements.set_prop("encryption", AAZObjectType, ".encryption"))
_elements.set_prop("excludeFromLatest", AAZBoolType, ".exclude_from_latest")
_elements.set_prop("name", AAZStrType, ".name", typ_kwargs={"flags": {"required": True}})
_elements.set_prop("regionalReplicaCount", AAZIntType, ".regional_replica_count")
_elements.set_prop("storageAccountType", AAZStrType, ".storage_account_type")

additional_replica_sets = _builder.get(".properties.publishingProfile.targetRegions[].additionalReplicaSets")
if additional_replica_sets is not None:
additional_replica_sets.set_elements(AAZObjectType, ".")

_elements = _builder.get(".properties.publishingProfile.targetRegions[].additionalReplicaSets[]")
if _elements is not None:
_elements.set_prop("regionalReplicaCount", AAZIntType, ".regional_replica_count")
_elements.set_prop("storageAccountType", AAZStrType, ".storage_account_type")

safety_profile = _builder.get(".properties.safetyProfile")
if safety_profile is not None:
safety_profile.set_prop("allowDeletionOfReplicatedLocations", AAZBoolType, ".allow_deletion_of_replicated_locations")
safety_profile.set_prop("blockDeletionBeforeEndOfLife", AAZBoolType, ".block_deletion_before_end_of_life")

security_profile = _builder.get(".properties.securityProfile")
if security_profile is not None:
Expand Down Expand Up @@ -852,6 +891,7 @@ def _build_schema_gallery_image_version_read(cls, _schema):
serialized_name="replicationStatus",
flags={"read_only": True},
)
properties.restore = AAZBoolType()
properties.safety_profile = AAZObjectType(
serialized_name="safetyProfile",
)
Expand All @@ -862,6 +902,10 @@ def _build_schema_gallery_image_version_read(cls, _schema):
serialized_name="storageProfile",
flags={"required": True},
)
properties.validations_profile = AAZObjectType(
serialized_name="validationsProfile",
flags={"read_only": True},
)

publishing_profile = _schema_gallery_image_version_read.properties.publishing_profile
publishing_profile.end_of_life_date = AAZStrType(
Expand Down Expand Up @@ -915,6 +959,9 @@ def _build_schema_gallery_image_version_read(cls, _schema):
target_regions.Element = AAZObjectType()

_element = _schema_gallery_image_version_read.properties.publishing_profile.target_regions.Element
_element.additional_replica_sets = AAZListType(
serialized_name="additionalReplicaSets",
)
_element.encryption = AAZObjectType()
cls._build_schema_encryption_images_read(_element.encryption)
_element.exclude_from_latest = AAZBoolType(
Expand All @@ -930,6 +977,17 @@ def _build_schema_gallery_image_version_read(cls, _schema):
serialized_name="storageAccountType",
)

additional_replica_sets = _schema_gallery_image_version_read.properties.publishing_profile.target_regions.Element.additional_replica_sets
additional_replica_sets.Element = AAZObjectType()

_element = _schema_gallery_image_version_read.properties.publishing_profile.target_regions.Element.additional_replica_sets.Element
_element.regional_replica_count = AAZIntType(
serialized_name="regionalReplicaCount",
)
_element.storage_account_type = AAZStrType(
serialized_name="storageAccountType",
)

replication_status = _schema_gallery_image_version_read.properties.replication_status
replication_status.aggregated_state = AAZStrType(
serialized_name="aggregatedState",
Expand Down Expand Up @@ -960,6 +1018,9 @@ def _build_schema_gallery_image_version_read(cls, _schema):
safety_profile.allow_deletion_of_replicated_locations = AAZBoolType(
serialized_name="allowDeletionOfReplicatedLocations",
)
safety_profile.block_deletion_before_end_of_life = AAZBoolType(
serialized_name="blockDeletionBeforeEndOfLife",
)
safety_profile.policy_violations = AAZListType(
serialized_name="policyViolations",
flags={"read_only": True},
Expand Down Expand Up @@ -1057,6 +1118,39 @@ def _build_schema_gallery_image_version_read(cls, _schema):
serialized_name="virtualMachineId",
)

validations_profile = _schema_gallery_image_version_read.properties.validations_profile
validations_profile.executed_validations = AAZListType(
serialized_name="executedValidations",
)
validations_profile.platform_attributes = AAZListType(
serialized_name="platformAttributes",
)
validations_profile.validation_etag = AAZStrType(
serialized_name="validationEtag",
)

executed_validations = _schema_gallery_image_version_read.properties.validations_profile.executed_validations
executed_validations.Element = AAZObjectType()

_element = _schema_gallery_image_version_read.properties.validations_profile.executed_validations.Element
_element.execution_time = AAZStrType(
serialized_name="executionTime",
)
_element.status = AAZStrType()
_element.type = AAZStrType()
_element.version = AAZStrType()

platform_attributes = _schema_gallery_image_version_read.properties.validations_profile.platform_attributes
platform_attributes.Element = AAZObjectType()

_element = _schema_gallery_image_version_read.properties.validations_profile.platform_attributes.Element
_element.name = AAZStrType(
flags={"read_only": True},
)
_element.value = AAZStrType(
flags={"read_only": True},
)

tags = _schema_gallery_image_version_read.tags
tags.Element = AAZStrType()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ class Delete(AAZCommand):
"""

_aaz_info = {
"version": "2023-07-03",
"version": "2024-03-03",
"resources": [
["mgmt-plane", "/subscriptions/{}/resourcegroups/{}/providers/microsoft.compute/galleries/{}/images/{}/versions/{}", "2023-07-03"],
["mgmt-plane", "/subscriptions/{}/resourcegroups/{}/providers/microsoft.compute/galleries/{}/images/{}/versions/{}", "2024-03-03"],
]
}

Expand Down Expand Up @@ -159,7 +159,7 @@ def url_parameters(self):
def query_parameters(self):
parameters = {
**self.serialize_query_param(
"api-version", "2023-07-03",
"api-version", "2024-03-03",
required=True,
),
}
Expand Down
Loading
Loading