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: Add new parameters --virtual-machine and --image-version to support creating image version from different source #22645

Merged
merged 5 commits into from
Jun 1, 2022
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
12 changes: 6 additions & 6 deletions src/azure-cli/azure/cli/command_modules/vm/_help.py
Original file line number Diff line number Diff line change
Expand Up @@ -786,7 +786,7 @@
az sig image-version create --resource-group MyResourceGroup \\
--gallery-name MyGallery --gallery-image-definition MyImage \\
--gallery-image-version 1.0.0 \\
--managed-image /subscriptions/00000000-0000-0000-0000-00000000xxxx/resourceGroups/imageGroups/providers/Microsoft.Compute/virtualMachines/MyVM
--virtual-machine /subscriptions/00000000-0000-0000-0000-00000000xxxx/resourceGroups/imageGroups/providers/Microsoft.Compute/virtualMachines/MyVM
- name: Add a new image version from a managed image
text: |
az sig image-version create --resource-group MyResourceGroup \\
Expand All @@ -798,7 +798,7 @@
az sig image-version create --resource-group MyResourceGroup \\
--gallery-name MyGallery --gallery-image-definition MyImage \\
--gallery-image-version 1.0.0 \\
--managed-image /subscriptions/00000000-0000-0000-0000-00000000xxxx/resourceGroups/imageGroups/providers/Microsoft.Compute/galleries/MyGallery/images/MyImageDefinition/versions/1.0.0
--image-version /subscriptions/00000000-0000-0000-0000-00000000xxxx/resourceGroups/imageGroups/providers/Microsoft.Compute/galleries/MyGallery/images/MyImageDefinition/versions/1.0.0
- name: Add a new image version from a managed disk
text: |
az sig image-version create --resource-group MyResourceGroup \\
Expand Down Expand Up @@ -866,7 +866,7 @@
az sig image-version create --resource-group MyResourceGroup \\
--gallery-name MyGallery --gallery-image-definition MyImage \\
--gallery-image-version 1.0.0 \\
--managed-image /subscriptions/00000000-0000-0000-0000-00000000xxxx/resourceGroups/imageGroups/providers/Microsoft.Compute/virtualMachines/MyVM \\
--virtual-machine /subscriptions/00000000-0000-0000-0000-00000000xxxx/resourceGroups/imageGroups/providers/Microsoft.Compute/virtualMachines/MyVM \\
--target-regions westus=2=standard eastus \\
--target-region-encryption WestUSDiskEncryptionSet1,0,WestUSDiskEncryptionSet2 \\
EastUSDiskEncryptionSet1,0,EastUSDiskEncryptionSet2
Expand All @@ -875,21 +875,21 @@
az sig image-version create --resource-group MyResourceGroup \\
--gallery-name MyGallery --gallery-image-definition MyImage \\
--gallery-image-version 1.0.0 \\
--managed-image /subscriptions/00000000-0000-0000-0000-00000000xxxx/resourceGroups/imageGroups/providers/Microsoft.Compute/virtualMachines/MyVM \\
--virtual-machine /subscriptions/00000000-0000-0000-0000-00000000xxxx/resourceGroups/imageGroups/providers/Microsoft.Compute/virtualMachines/MyVM \\
--no-wait
- name: Add a new image version but remove it from consideration as latest version in its image definition
text: |
az sig image-version create --resource-group MyResourceGroup \\
--gallery-name MyGallery --gallery-image-definition MyImage \\
--gallery-image-version 1.0.0 \\
--managed-image /subscriptions/00000000-0000-0000-0000-00000000xxxx/resourceGroups/imageGroups/providers/Microsoft.Compute/virtualMachines/MyVM \\
--virtual-machine /subscriptions/00000000-0000-0000-0000-00000000xxxx/resourceGroups/imageGroups/providers/Microsoft.Compute/virtualMachines/MyVM \\
--exclude-from-latest true
- name: Add a new image version and set its end-of-life date. The image version can still be used to create a virtual machine after its end-of-life date.
text: |
az sig image-version create --resource-group MyResourceGroup \\
--gallery-name MyGallery --gallery-image-definition MyImage \\
--gallery-image-version 1.0.0 \\
--managed-image /subscriptions/00000000-0000-0000-0000-00000000xxxx/resourceGroups/imageGroups/providers/Microsoft.Compute/virtualMachines/MyVM \\
--virtual-machine /subscriptions/00000000-0000-0000-0000-00000000xxxx/resourceGroups/imageGroups/providers/Microsoft.Compute/virtualMachines/MyVM \\
--end-of-life-date 2024-08-02T00:00:00+00:00
"""

Expand Down
6 changes: 4 additions & 2 deletions src/azure-cli/azure/cli/command_modules/vm/_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
from azure.cli.command_modules.vm._validators import (
validate_nsg_name, validate_vm_nics, validate_vm_nic, validate_vmss_disk,
validate_asg_names_or_ids, validate_keyvault, _validate_proximity_placement_group,
process_gallery_image_version_namespace, validate_vm_name_for_monitor_metrics)
validate_vm_name_for_monitor_metrics)

from azure.cli.command_modules.vm._vm_utils import MSI_LOCAL_ID
from azure.cli.command_modules.vm._image_builder import ScriptType
Expand Down Expand Up @@ -1244,6 +1244,8 @@ def load_arguments(self, _):
c.argument('data_vhds_storage_accounts', options_list=['--data-vhds-storage-accounts', '--data-vhds-sa'], nargs='+', help='Names or IDs (space-delimited) of storage accounts of source VHD URIs of data disks')
c.argument('replication_mode', min_api='2021-07-01', arg_type=get_enum_type(ReplicationMode), help='Optional parameter which specifies the mode to be used for replication. This property is not updatable.')
c.argument('target_region_cvm_encryption', nargs='+', min_api='2021-10-01', help='Space-separated list of customer managed key for Confidential VM encrypting the OS disk in the gallery artifact for each region. Format for each region: `<os_cvm_encryption_type>,<os_cvm_des>`. The valid values for os_cvm_encryption_type are EncryptedVMGuestStateOnlyWithPmk, EncryptedWithPmk, EncryptedWithCmk.')
c.argument('virtual_machine', help='Resource id of VM source')
c.argument('image_version', help='Resource id of gallery image version source')

with self.argument_context('sig image-version list-shared') as c:
c.argument('location', arg_type=get_location_type(self.cli_ctx), id_part='name')
Expand Down Expand Up @@ -1273,7 +1275,7 @@ def load_arguments(self, _):

for scope in ['sig image-version create', 'sig image-version update']:
with self.argument_context(scope) as c:
c.argument('target_regions', nargs='*', validator=process_gallery_image_version_namespace,
Copy link
Contributor

Choose a reason for hiding this comment

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

Since command sig image-version update also called validator=process_gallery_image_version_namespace, we may add a command level validator for command sig image-version update, and then call process_gallery_image_version_namespace in the command level validator

c.argument('target_regions', nargs='*',
help='Space-separated list of regions and their replica counts. Use `<region>[=<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')
c.argument('replica_count', help='The default number of replicas to be created per region. To set regional replication counts, use --target-regions', type=int)
Expand Down
39 changes: 39 additions & 0 deletions src/azure-cli/azure/cli/command_modules/vm/_validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -1992,6 +1992,45 @@ def _disk_encryption_set_format(cmd, namespace, name):
# endregion


def process_image_version_create_namespace(cmd, namespace):
process_gallery_image_version_namespace(cmd, namespace)
process_image_resource_id_namespace(namespace)
# endregion


def process_image_version_update_namespace(cmd, namespace):
process_gallery_image_version_namespace(cmd, namespace)
# endregion


def process_image_resource_id_namespace(namespace):
"""
Validate the resource id from different sources
Only one of these arguments is allowed to provide
Check the format of resource id whether meets requirement
"""
input_num = (1 if namespace.managed_image else 0) + (1 if namespace.virtual_machine else 0) + \
(1 if namespace.image_version else 0)
if input_num > 1:
raise MutuallyExclusiveArgumentError(
r'usage error: please specify only one of the --managed-image\--virtual-machine\--image-version arguments')

if namespace.managed_image or input_num == 0:
return

from ._vm_utils import is_valid_vm_resource_id, is_valid_image_version_id
is_vm = namespace.virtual_machine is not None
is_valid_function = is_valid_vm_resource_id if is_vm else is_valid_image_version_id
resource_id = namespace.virtual_machine if is_vm else namespace.image_version

if not is_valid_function(resource_id):
from azure.cli.core.parser import InvalidArgumentValueError
raise InvalidArgumentValueError('usage error: {} is an invalid {} id'
.format(resource_id, 'VM resource' if is_vm else 'gallery image version'))
namespace.managed_image = resource_id
# endregion


def process_vm_vmss_stop(cmd, namespace): # pylint: disable=unused-argument
if "vmss" in cmd.name:
logger.warning("About to power off the VMSS instances...\nThey will continue to be billed. "
Expand Down
30 changes: 26 additions & 4 deletions src/azure-cli/azure/cli/command_modules/vm/_vm_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@

logger = get_logger(__name__)


MSI_LOCAL_ID = '[system]'


Expand Down Expand Up @@ -149,7 +148,8 @@ def normalize_disk_info(image_data_disks=None,
if attach_data_disks:
data_disk_delete_option = validate_delete_options(attach_data_disks, data_disk_delete_option)
else:
if isinstance(data_disk_delete_option, list) and len(data_disk_delete_option) == 1 and len(data_disk_delete_option[0].split('=')) == 1: # pylint: disable=line-too-long
if isinstance(data_disk_delete_option, list) and len(data_disk_delete_option) == 1 and len(
data_disk_delete_option[0].split('=')) == 1: # pylint: disable=line-too-long
data_disk_delete_option = data_disk_delete_option[0]
info['os'] = {}
# update os diff disk settings
Expand Down Expand Up @@ -254,7 +254,6 @@ def normalize_disk_info(image_data_disks=None,


def update_disk_caching(model, caching_settings):

def _update(model, lun, value):
if isinstance(model, dict):
luns = model.keys() if lun is None else [lun]
Expand Down Expand Up @@ -289,7 +288,6 @@ def _update(model, lun, value):


def update_write_accelerator_settings(model, write_accelerator_settings):

def _update(model, lun, value):
if isinstance(model, dict):
luns = model.keys() if lun is None else [lun]
Expand Down Expand Up @@ -380,6 +378,30 @@ def is_shared_gallery_image_id(image_reference):
return False


def is_valid_vm_resource_id(vm_resource_id):
if not vm_resource_id:
return False

vm_id_pattern = re.compile(r'^/subscriptions/[^/]*/resourceGroups/[^/]*/providers/Microsoft.Compute/'
r'virtualMachines/.*$', re.IGNORECASE)
if vm_id_pattern.match(vm_resource_id):
return True

return False


def is_valid_image_version_id(image_version_id):
if not image_version_id:
return False

image_version_id_pattern = re.compile(r'^/subscriptions/[^/]*/resourceGroups/[^/]*/providers/Microsoft.Compute/'
r'galleries/[^/]*/images/[^/]*/versions/.*$', re.IGNORECASE)
if image_version_id_pattern.match(image_version_id):
return True

return False


def parse_shared_gallery_image_id(image_reference):
from azure.cli.core.azclierror import InvalidArgumentValueError

Expand Down
7 changes: 4 additions & 3 deletions src/azure-cli/azure/cli/command_modules/vm/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@
process_vm_create_namespace, process_vmss_create_namespace, process_image_create_namespace,
process_disk_or_snapshot_create_namespace, process_disk_encryption_namespace, process_assign_identity_namespace,
process_remove_identity_namespace, process_vm_secret_format, process_vm_vmss_stop, validate_vmss_update_namespace,
process_vm_update_namespace, process_set_applications_namespace, process_vm_disk_attach_namespace)
process_vm_update_namespace, process_set_applications_namespace, process_vm_disk_attach_namespace,
process_image_version_create_namespace, process_image_version_update_namespace)

from azure.cli.command_modules.vm._image_builder import (
process_image_template_create_namespace, process_img_tmpl_output_add_namespace,
Expand Down Expand Up @@ -539,8 +540,8 @@ def load_command_table(self, _):
g.command('delete', 'begin_delete')
g.show_command('show', 'get', table_transformer='{Name:name, ResourceGroup:resourceGroup, ProvisioningState:provisioningState, TargetRegions: publishingProfile.targetRegions && join(`, `, publishingProfile.targetRegions[*].name), ReplicationState:replicationStatus.aggregatedState}')
g.command('list', 'list_by_gallery_image')
g.custom_command('create', 'create_image_version', supports_no_wait=True)
g.generic_update_command('update', getter_name='get_image_version_to_update', setter_arg_name='gallery_image_version', setter_name='update_image_version', setter_type=compute_custom, command_type=compute_custom, supports_no_wait=True)
g.custom_command('create', 'create_image_version', supports_no_wait=True, validator=process_image_version_create_namespace)
g.generic_update_command('update', getter_name='get_image_version_to_update', setter_arg_name='gallery_image_version', setter_name='update_image_version', setter_type=compute_custom, command_type=compute_custom, supports_no_wait=True, validator=process_image_version_update_namespace)
g.wait_command('wait')

vm_shared_gallery = CliCommandType(
Expand Down
3 changes: 2 additions & 1 deletion src/azure-cli/azure/cli/command_modules/vm/custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -4199,7 +4199,8 @@ def create_image_version(cmd, resource_group_name, gallery_name, gallery_image_n
os_snapshot=None, data_snapshots=None, managed_image=None, data_snapshot_luns=None,
target_region_encryption=None, os_vhd_uri=None, os_vhd_storage_account=None,
data_vhds_uris=None, data_vhds_luns=None, data_vhds_storage_accounts=None,
replication_mode=None, target_region_cvm_encryption=None):
replication_mode=None, target_region_cvm_encryption=None, virtual_machine=None,
image_version=None):
from msrestazure.tools import resource_id, is_valid_resource_id
from azure.cli.core.commands.client_factory import get_subscription_id

Expand Down
Loading