From e94ecedc2c91269f13ac917f11903f2991bb1e5d Mon Sep 17 00:00:00 2001 From: Zunli Hu Date: Wed, 23 Jun 2021 10:13:22 +0800 Subject: [PATCH] [Compute] Direct sharing support (#18503) * init * 'test' * update test * update test * test recording * style * remove generated test * add command to get shared galleries * fix test * wait command * Update src/azure-cli/azure/cli/command_modules/vm/generated/_help.py Co-authored-by: Feiyue Yu * delete sig share update * change the command format * lint * remove is_experimental * update command design * update command name and enum value * add wait command * linter * Update src/azure-cli/azure/cli/command_modules/vm/manual/_help.py Co-authored-by: Feiyue Yu * Update src/azure-cli/azure/cli/command_modules/vm/manual/_help.py Co-authored-by: Feiyue Yu * Update src/azure-cli/azure/cli/command_modules/vm/generated/_params.py Co-authored-by: Feiyue Yu * help info * regenerate command interface but manual not work * test pass * fix test * resolve comments * fix style * Update src/azure-cli/azure/cli/command_modules/vm/manual/_help.py Co-authored-by: xfz11 <81600993+xfz11@users.noreply.github.com> * test pass * revert * revert * delete * fix typo * refine help * Apply suggestions from code review Co-authored-by: Xing Zhou * add permission to create Co-authored-by: xiaofanzhou Co-authored-by: xfz11 <81600993+xfz11@users.noreply.github.com> Co-authored-by: Feiyue Yu Co-authored-by: Xing Zhou --- .../azure/cli/core/profiles/_shared.py | 3 +- .../cli/command_modules/vm/_client_factory.py | 23 + .../azure/cli/command_modules/vm/_help.py | 116 +- .../azure/cli/command_modules/vm/_params.py | 76 + .../azure/cli/command_modules/vm/commands.py | 53 +- .../azure/cli/command_modules/vm/custom.py | 87 +- .../azure/cli/command_modules/vm/gen.zip | Bin 3674 -> 5436 bytes .../latest/recordings/test_gallery_e2e.yaml | 1697 +++---- .../recordings/test_gallery_specialized.yaml | 4 +- .../test_image_build_shared_image.yaml | 4 +- .../test_image_builder_basic_sig.yaml | 4 +- .../recordings/test_shared_gallery.yaml | 3881 +++++++++++++++++ .../recordings/test_specialized_image.yaml | 4 +- .../test_vm_disk_max_shares_etc.yaml | 4 +- .../vm/tests/latest/test_vm_commands.py | 100 + 15 files changed, 5301 insertions(+), 755 deletions(-) create mode 100644 src/azure-cli/azure/cli/command_modules/vm/tests/latest/recordings/test_shared_gallery.yaml diff --git a/src/azure-cli-core/azure/cli/core/profiles/_shared.py b/src/azure-cli-core/azure/cli/core/profiles/_shared.py index d5e3fd1badf..85aacf44150 100644 --- a/src/azure-cli-core/azure/cli/core/profiles/_shared.py +++ b/src/azure-cli-core/azure/cli/core/profiles/_shared.py @@ -144,9 +144,10 @@ def default_api_version(self): 'disk_encryption_sets': '2020-12-01', 'disk_accesses': '2020-05-01', 'snapshots': '2020-12-01', - 'galleries': '2019-12-01', + 'galleries': '2020-09-30', 'gallery_images': '2020-09-30', 'gallery_image_versions': '2020-09-30', + 'shared_galleries': '2020-09-30', 'virtual_machine_scale_sets': '2021-03-01' }), ResourceType.MGMT_RESOURCE_FEATURES: '2015-12-01', diff --git a/src/azure-cli/azure/cli/command_modules/vm/_client_factory.py b/src/azure-cli/azure/cli/command_modules/vm/_client_factory.py index a0d3a8e2d82..77f3800a69a 100644 --- a/src/azure-cli/azure/cli/command_modules/vm/_client_factory.py +++ b/src/azure-cli/azure/cli/command_modules/vm/_client_factory.py @@ -155,3 +155,26 @@ def _dev_test_labs_client_factory(cli_ctx, subscription_id, *_): from azure.mgmt.devtestlabs import DevTestLabsClient from azure.cli.core.commands.client_factory import get_mgmt_service_client return get_mgmt_service_client(cli_ctx, DevTestLabsClient, subscription_id=subscription_id) + + +def cf_vm_cl(cli_ctx, *_): + from azure.cli.core.commands.client_factory import get_mgmt_service_client + from azure.mgmt.compute import ComputeManagementClient + return get_mgmt_service_client(cli_ctx, + ComputeManagementClient) + + +def cf_shared_galleries(cli_ctx, *_): + return cf_vm_cl(cli_ctx).shared_galleries + + +def cf_gallery_sharing_profile(cli_ctx, *_): + return cf_vm_cl(cli_ctx).gallery_sharing_profile + + +def cf_shared_gallery_image(cli_ctx, *_): + return cf_vm_cl(cli_ctx).shared_gallery_images + + +def cf_shared_gallery_image_version(cli_ctx, *_): + return cf_vm_cl(cli_ctx).shared_gallery_image_versions diff --git a/src/azure-cli/azure/cli/command_modules/vm/_help.py b/src/azure-cli/azure/cli/command_modules/vm/_help.py index 3a0035bee1b..2f27892bc80 100644 --- a/src/azure-cli/azure/cli/command_modules/vm/_help.py +++ b/src/azure-cli/azure/cli/command_modules/vm/_help.py @@ -599,7 +599,7 @@ helps['sig image-definition'] = """ type: group -short-summary: create an image definition +short-summary: Manage shared gallery image with VM """ helps['sig image-definition create'] = """ @@ -611,6 +611,28 @@ az sig image-definition create -g MyResourceGroup --gallery-name MyGallery --gallery-image-definition MyImage --publisher GreatPublisher --offer GreatOffer --sku GreatSku --os-type linux """ +helps['sig image-definition list-shared'] = """ +type: command +short-summary: List shared gallery images by subscription id or tenant id. +examples: + - name: List shared images by subscription id. + text: |- + az sig image-definition list-shared --gallery-unique-name "galleryUniqueName" --location "myLocation" + - name: List shared images by tenant id. + text: |- + az sig image-definition list-shared --gallery-unique-name "galleryUniqueName" --location "myLocation" --shared-to tenant +""" + +helps['sig image-definition show-shared'] = """ +type: command +short-summary: Get a shared gallery image. +examples: + - name: Get a shared gallery image. + text: |- + az sig image-definition show-shared --gallery-image-definition "myGalleryImageName" \ +--gallery-unique-name "galleryUniqueName" --location "myLocation" +""" + helps['sig image-definition update'] = """ type: command short-summary: update a share image defintiion. @@ -623,7 +645,7 @@ helps['sig image-version'] = """ type: group -short-summary: create a new version from an image defintion +short-summary: Manage shared gallery image version with VM """ helps['sig image-version create'] = """ @@ -684,6 +706,30 @@ az sig image-version create -g MyResourceGroup --gallery-name MyGallery --gallery-image-definition MyImage --gallery-image-version 1.0.0 --os-vhd-uri --os-vhd-storage-account account """ +helps['sig image-version list-shared'] = """ +type: command +short-summary: List shared gallery image versions by subscription id or tenant id. +examples: + - name: List shared image versions by subscription id. + text: |- + az sig image-version list-shared --gallery-image-definition "myGalleryImageName" --gallery-unique-name \ +"galleryUniqueName" --location "myLocation" + - name: List shared image versions by tenant id. + text: |- + az sig image-version list-shared --gallery-image-definition "myGalleryImageName" --gallery-unique-name \ +"galleryUniqueName" --location "myLocation" --shared-to tenant +""" + +helps['sig image-version show-shared'] = """ +type: command +short-summary: Get a shared gallery image version. +examples: + - name: Get a shared gallery image version. + text: |- + az sig image-version show-shared --gallery-image-definition "myGalleryImageName" \ +--gallery-image-version "myGalleryImageVersionName" --gallery-unique-name "galleryUniqueName" --location "myLocation" +""" + helps['sig image-version update'] = """ type: command short-summary: update a share image version @@ -722,11 +768,77 @@ crafted: true """ +helps['sig list-shared'] = """ +type: command +short-summary: List shared galleries by subscription id or tenant id. +examples: + - name: List shared galleries by subscription id. + text: |- + az sig list-shared --location "myLocation" + - name: List shared galleries by tenant id. + text: |- + az sig list-shared --location "myLocation" --shared-to tenant +""" + helps['sig list'] = """ type: command short-summary: list share image galleries. """ +helps['sig share'] = """ +type: group +short-summary: Manage gallery sharing profile +""" + +helps['sig share add'] = """ +type: command +short-summary: Add sharing id to the sharing profile of a gallery. +examples: + - name: Add sharing id to the sharing profile of a gallery. + text: |- + az sig share add --gallery-name "myGalleryName" --resource-group "myResourceGroup" \ +--subscription-ids "34a4ab42-0d72-47d9-bd1a-aed207386dac" "380fd389-260b-41aa-bad9-0a83108c370b" \ +--tenant-ids "c24c76aa-8897-4027-9b03-8f7928b54ff6" +""" + +helps['sig share remove'] = """ +type: command +short-summary: Remove sharing profile of a gallery. +examples: + - name: Remove sharing ID to the sharing profile of a gallery. + text: |- + az sig share remove --gallery-name "myGalleryName" --resource-group "myResourceGroup" \ +--subscription-ids "34a4ab42-0d72-47d9-bd1a-aed207386dac" "380fd389-260b-41aa-bad9-0a83108c370b" \ +--tenant-ids "c24c76aa-8897-4027-9b03-8f7928b54ff6" +""" + +helps['sig share reset'] = """ +type: command +short-summary: Reset sharing profile of a gallery. +examples: + - name: Reset sharing profile of a gallery. + text: |- + az sig share reset --gallery-name "myGalleryName" --resource-group "myResourceGroup" +""" + +helps['sig share wait'] = """ +type: command +short-summary: Place the CLI in a waiting state until a condition of a shared gallery is met. +examples: + - name: Place the CLI in a waiting state until the gallery sharing object is updated. + text: | + az sig share wait --updated -g MyResourceGroup --gallery-name Gallery +""" + +helps['sig show-shared'] = """ +type: command +short-summary: Get a shared gallery. +examples: + - name: Get a shared gallery. + text: |- + az sig show-shared --gallery-unique-name "galleryUniqueName" --location "myLocation" +""" + helps['sig update'] = """ type: command short-summary: update a share image gallery. diff --git a/src/azure-cli/azure/cli/command_modules/vm/_params.py b/src/azure-cli/azure/cli/command_modules/vm/_params.py index 43309c2c668..ce217e15bb6 100644 --- a/src/azure-cli/azure/cli/command_modules/vm/_params.py +++ b/src/azure-cli/azure/cli/command_modules/vm/_params.py @@ -41,6 +41,7 @@ def load_arguments(self, _): DedicatedHostLicenseTypes = self.get_models('DedicatedHostLicenseTypes') OrchestrationServiceNames, OrchestrationServiceStateAction = self.get_models('OrchestrationServiceNames', 'OrchestrationServiceStateAction', operation_group='virtual_machine_scale_sets') RebootSetting, VMGuestPatchClassificationWindows, VMGuestPatchClassificationLinux = self.get_models('VMGuestPatchRebootSetting', 'VMGuestPatchClassificationWindows', 'VMGuestPatchClassificationLinux') + GallerySharingPermissionTypes = self.get_models('GallerySharingPermissionTypes', operation_group='shared_galleries') # REUSABLE ARGUMENT DEFINITIONS name_arg_type = CLIArgumentType(options_list=['--name', '-n'], metavar='NAME') @@ -103,6 +104,13 @@ def load_arguments(self, _): is_preview=True ) + t_shared_to = self.get_models('SharedToValues', operation_group='shared_galleries') + shared_to_type = CLIArgumentType( + arg_type=get_enum_type(t_shared_to), + help='The query parameter to decide what shared galleries to fetch when doing listing operations. ' + 'If not specified, list by subscription id.' + ) + # region MixedScopes for scope in ['vm', 'disk', 'snapshot', 'image', 'sig']: with self.argument_context(scope) as c: @@ -917,6 +925,32 @@ def load_arguments(self, _): c.argument('gallery_name', options_list=['--gallery-name', '-r'], id_part='name', help='gallery name') c.argument('gallery_image_name', options_list=['--gallery-image-definition', '-i'], id_part='child_name_1', help='gallery image definition') + with self.argument_context('sig list-shared') as c: + c.argument('location', arg_type=get_location_type(self.cli_ctx)) + c.argument('shared_to', shared_to_type) + + with self.argument_context('sig show-shared') as c: + c.argument('location', arg_type=get_location_type(self.cli_ctx), id_part='name') + c.argument('gallery_unique_name', type=str, help='The unique name of the Shared Gallery.', + id_part='child_name_1') + + for scope in ['sig share add', 'sig share remove']: + with self.argument_context(scope) as c: + c.argument('gallery_name', type=str, help='The name of the Shared Image Gallery.', id_part='name') + c.argument('subscription_ids', nargs='+', help='A list of subscription ids to share the gallery.') + c.argument('tenant_ids', nargs='+', help='A list of tenant ids to share the gallery.') + + with self.argument_context('sig share add') as c: + c.argument('op_type', default='Add', deprecate_info=c.deprecate(hide=True), + help='distinguish add operation and remove operation') + + with self.argument_context('sig share remove') as c: + c.argument('op_type', default='Remove', deprecate_info=c.deprecate(hide=True), + help='distinguish add operation and remove operation') + + with self.argument_context('sig share reset') as c: + c.argument('gallery_name', type=str, help='The name of the Shared Image Gallery.', id_part='name') + with self.argument_context('sig image-definition create') as c: c.argument('offer', options_list=['--offer', '-f'], help='image offer') c.argument('sku', options_list=['--sku', '-s'], help='image sku') @@ -940,10 +974,31 @@ def load_arguments(self, _): c.argument('disallowed_disk_types', nargs='*', help='disk types which would not work with the image, e.g., Standard_LRS') c.argument('features', help='A list of gallery image features. E.g. "IsSecureBootSupported=true IsMeasuredBootSupported=false"') + with self.argument_context('sig image-definition list-shared') as c: + c.argument('location', arg_type=get_location_type(self.cli_ctx), id_part='name') + c.argument('gallery_unique_name', type=str, help='The unique name of the Shared Gallery.', + id_part='child_name_1') + c.argument('shared_to', shared_to_type) + + with self.argument_context('sig image-definition show-shared') as c: + c.argument('location', arg_type=get_location_type(self.cli_ctx), id_part='name') + c.argument('gallery_unique_name', type=str, help='The unique name of the Shared Gallery.', + id_part='child_name_1') + c.argument('gallery_image_name', options_list=['--gallery-image-definition', '-i'], type=str, help='The name ' + 'of the Shared Gallery Image Definition from which the Image Versions are to be listed.', + id_part='child_name_2') + with self.argument_context('sig create') as c: c.argument('description', help='the description of the gallery') + c.argument('permissions', arg_type=get_enum_type(GallerySharingPermissionTypes), arg_group='Sharing Profile', + min_api='2020-09-30', is_experimental=True, + help='This property allows you to specify the permission of sharing gallery.') with self.argument_context('sig update') as c: c.ignore('gallery') + c.argument('permissions', arg_type=get_enum_type(GallerySharingPermissionTypes), arg_group='Sharing Profile', + min_api='2020-09-30', is_experimental=True, + help='This property allows you to specify the permission of sharing gallery.') + with self.argument_context('sig image-definition create') as c: c.argument('description', help='the description of the gallery image definition') with self.argument_context('sig image-definition update') as c: @@ -975,9 +1030,30 @@ def load_arguments(self, _): c.argument('data_vhds_luns', nargs='+', help='Logical unit numbers (space-delimited) of source VHD URIs of data disks') 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') + 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') + c.argument('gallery_unique_name', type=str, help='The unique name of the Shared Gallery.', + id_part='child_name_1') + c.argument('gallery_image_name', options_list=['--gallery-image-definition', '-i'], type=str, help='The name ' + 'of the Shared Gallery Image Definition from which the Image Versions are to be listed.', + id_part='child_name_2') + c.argument('shared_to', shared_to_type) + with self.argument_context('sig image-version show') as c: c.argument('expand', help="The expand expression to apply on the operation, e.g. 'ReplicationStatus'") + with self.argument_context('sig image-version show-shared') as c: + c.argument('location', arg_type=get_location_type(self.cli_ctx), id_part='name') + c.argument('gallery_unique_name', type=str, help='The unique name of the Shared Gallery.', + id_part='child_name_1') + c.argument('gallery_image_name', options_list=['--gallery-image-definition', '-i'], type=str, help='The name ' + 'of the Shared Gallery Image Definition from which the Image Versions are to be listed.', + id_part='child_name_2') + c.argument('gallery_image_version_name', options_list=['--gallery-image-version', '-e'], type=str, help='The ' + 'name of the gallery image version to be created. Needs to follow semantic version name pattern: ' + 'The allowed characters are digit and period. Digits must be within the range of a 32-bit integer. ' + 'Format: ..', id_part='child_name_3') + 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, diff --git a/src/azure-cli/azure/cli/command_modules/vm/commands.py b/src/azure-cli/azure/cli/command_modules/vm/commands.py index 3a645e78dd0..799acc904a3 100644 --- a/src/azure-cli/azure/cli/command_modules/vm/commands.py +++ b/src/azure-cli/azure/cli/command_modules/vm/commands.py @@ -14,7 +14,9 @@ cf_proximity_placement_groups, cf_dedicated_hosts, cf_dedicated_host_groups, cf_log_analytics_data_plane, - cf_disk_encryption_set) + cf_disk_encryption_set, cf_shared_galleries, + cf_gallery_sharing_profile, cf_shared_gallery_image, + cf_shared_gallery_image_version) from azure.cli.command_modules.vm._format import ( transform_ip_addresses, transform_vm, transform_vm_create_output, transform_vm_usage_list, transform_vm_list, transform_sku_for_table_output, transform_disk_show_table_output, transform_extension_show_table_output, @@ -471,7 +473,7 @@ def load_command_table(self, _): g.show_command('show', 'get') g.custom_command('list', 'list_image_galleries') g.command('delete', 'begin_delete') - g.generic_update_command('update', setter_name='begin_create_or_update', setter_arg_name='gallery') + g.generic_update_command('update', setter_type=compute_custom, setter_name='update_image_galleries', setter_arg_name='gallery') with self.command_group('sig image-definition', compute_gallery_images_sdk, operation_group='gallery_images', min_api='2018-06-01') as g: g.custom_command('create', 'create_gallery_image') @@ -488,6 +490,53 @@ def load_command_table(self, _): 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.wait_command('wait') + vm_shared_gallery = CliCommandType( + operations_tmpl='azure.mgmt.compute.operations._shared_galleries_operations#SharedGalleriesOperations.{}', + client_factory=cf_shared_galleries, + operation_group='shared_galleries' + ) + with self.command_group('sig', vm_shared_gallery) as g: + g.custom_command('list-shared', 'sig_shared_gallery_list', client_factory=cf_shared_galleries, + is_experimental=True, operation_group='shared_galleries', min_api='2020-09-30') + g.command('show-shared', 'get', is_experimental=True, operation_group='shared_galleries', min_api='2020-09-30') + + vm_gallery_sharing_profile = CliCommandType( + operations_tmpl=( + 'azure.mgmt.compute.operations._gallery_sharing_profile_operations#GallerySharingProfileOperations.{}' + ), + client_factory=cf_gallery_sharing_profile, + operation_group='shared_galleries' + ) + with self.command_group('sig share', vm_gallery_sharing_profile, + client_factory=cf_gallery_sharing_profile, + operation_group='shared_galleries', + is_experimental=True, min_api='2020-09-30') as g: + g.custom_command('add', 'sig_share_update', supports_no_wait=True) + g.custom_command('remove', 'sig_share_update', supports_no_wait=True) + g.custom_command('reset', 'sig_share_reset', supports_no_wait=True) + g.wait_command('wait', getter_name='get_gallery_instance', getter_type=compute_custom) + + vm_shared_gallery_image = CliCommandType( + operations_tmpl='azure.mgmt.compute.operations._shared_gallery_images_operations#SharedGalleryImagesOperations.' + '{}', + client_factory=cf_shared_gallery_image, + operation_group='shared_galleries') + with self.command_group('sig image-definition', vm_shared_gallery_image, min_api='2020-09-30', operation_group='shared_galleries', + client_factory=cf_shared_gallery_image) as g: + g.custom_command('list-shared', 'sig_shared_image_definition_list', is_experimental=True) + g.command('show-shared', 'get', is_experimental=True) + + vm_shared_gallery_image_version = CliCommandType( + operations_tmpl='azure.mgmt.compute.operations._shared_gallery_image_versions_operations#SharedGalleryImageVers' + 'ionsOperations.{}', + client_factory=cf_shared_gallery_image_version, + operation_group='shared_galleries') + with self.command_group('sig image-version', vm_shared_gallery_image_version, min_api='2020-09-30', + operation_group='shared_galleries', + client_factory=cf_shared_gallery_image_version) as g: + g.custom_command('list-shared', 'sig_shared_image_version_list', is_experimental=True) + g.command('show-shared', 'get', is_experimental=True) + with self.command_group('ppg', compute_proximity_placement_groups_sdk, min_api='2018-04-01', client_factory=cf_proximity_placement_groups) as g: g.show_command('show', 'get') g.custom_command('create', 'create_proximity_placement_group') diff --git a/src/azure-cli/azure/cli/command_modules/vm/custom.py b/src/azure-cli/azure/cli/command_modules/vm/custom.py index c889c478215..df4b5b34d80 100644 --- a/src/azure-cli/azure/cli/command_modules/vm/custom.py +++ b/src/azure-cli/azure/cli/command_modules/vm/custom.py @@ -26,10 +26,9 @@ from knack.log import get_logger from knack.util import CLIError -from azure.cli.core.azclierror import CLIInternalError +from azure.cli.core.azclierror import CLIInternalError, ValidationError, RequiredArgumentMissingError from azure.cli.command_modules.vm._validators import _get_resource_group_from_vault_name -from azure.cli.core.azclierror import ValidationError from azure.cli.core.commands.validators import validate_file_or_dict from azure.cli.core.commands import LongRunningOperation, DeploymentOutputLongRunningOperation @@ -1834,8 +1833,7 @@ def list_vm_images(cmd, image_location=None, publisher_name=None, offer=None, sk def show_vm_image(cmd, urn=None, publisher=None, offer=None, sku=None, version=None, location=None): from azure.cli.core.commands.parameters import get_one_of_subscription_locations from azure.cli.core.azclierror import (MutuallyExclusiveArgumentError, - InvalidArgumentValueError, - RequiredArgumentMissingError) + InvalidArgumentValueError) location = location or get_one_of_subscription_locations(cmd.cli_ctx) error_msg = 'Please specify all of (--publisher, --offer, --sku, --version), or --urn' @@ -1859,8 +1857,7 @@ def accept_market_ordering_terms(cmd, urn=None, publisher=None, offer=None, plan from azure.mgmt.marketplaceordering import MarketplaceOrderingAgreements from azure.mgmt.marketplaceordering.models import OfferType from azure.cli.core.azclierror import (MutuallyExclusiveArgumentError, - InvalidArgumentValueError, - RequiredArgumentMissingError) + InvalidArgumentValueError) error_msg = 'Please specify all of (--plan, --offer, --publish), or --urn' if urn: @@ -3365,14 +3362,32 @@ def list_image_galleries(cmd, resource_group_name=None): return client.galleries.list() +# from azure.mgmt.compute.models import Gallery, SharingProfile +def update_image_galleries(cmd, resource_group_name, gallery_name, gallery, permissions=None, **kwargs): + if permissions: + if gallery.sharing_profile is None: + SharingProfile = cmd.get_models('SharingProfile', operation_group='shared_galleries') + gallery.sharing_profile = SharingProfile(permissions=permissions) + else: + gallery.sharing_profile.permissions = permissions + + client = _compute_client_factory(cmd.cli_ctx) + + return client.galleries.begin_create_or_update(resource_group_name, gallery_name, gallery, **kwargs) + + def create_image_gallery(cmd, resource_group_name, gallery_name, description=None, - location=None, no_wait=False, tags=None): + location=None, no_wait=False, tags=None, permissions=None): Gallery = cmd.get_models('Gallery') location = location or _get_resource_group_location(cmd.cli_ctx, resource_group_name) gallery = Gallery(description=description, location=location, tags=(tags or {})) client = _compute_client_factory(cmd.cli_ctx) + if permissions: + SharingProfile = cmd.get_models('SharingProfile', operation_group='shared_galleries') + gallery.sharing_profile = SharingProfile(permissions=permissions) + return sdk_no_wait(no_wait, client.galleries.begin_create_or_update, resource_group_name, gallery_name, gallery) @@ -3855,3 +3870,61 @@ def install_vm_patches(cmd, client, resource_group_name, vm_name, maximum_durati return sdk_no_wait(no_wait, client.begin_install_patches, resource_group_name=resource_group_name, vm_name=vm_name, install_patches_input=install_patches_input) # endregion + + +def sig_shared_gallery_list(client, location, shared_to=None): + # Keep it here as it will add subscription in the future and we need to set it to None to make it work + if shared_to == 'subscription': + shared_to = None + return client.list(location=location, + shared_to=shared_to) + + +def sig_share_update(cmd, client, resource_group_name, gallery_name, subscription_ids=None, tenant_ids=None, + op_type=None): + SharingProfileGroup, SharingUpdate, SharingProfileGroupTypes = cmd.get_models( + 'SharingProfileGroup', 'SharingUpdate', 'SharingProfileGroupTypes', operation_group='shared_galleries') + if subscription_ids is None and tenant_ids is None: + raise RequiredArgumentMissingError('At least one of subscription ids or tenant ids must be provided') + groups = [] + if subscription_ids: + groups.append(SharingProfileGroup(type=SharingProfileGroupTypes.SUBSCRIPTIONS, ids=subscription_ids)) + if tenant_ids: + groups.append(SharingProfileGroup(type=SharingProfileGroupTypes.AAD_TENANTS, ids=tenant_ids)) + sharing_update = SharingUpdate(operation_type=op_type, groups=groups) + return client.begin_update(resource_group_name=resource_group_name, + gallery_name=gallery_name, + sharing_update=sharing_update) + + +def sig_share_reset(cmd, client, resource_group_name, gallery_name): + SharingUpdate, SharingUpdateOperationTypes = cmd.get_models('SharingUpdate', 'SharingUpdateOperationTypes', + operation_group='shared_galleries') + sharing_update = SharingUpdate(operation_type=SharingUpdateOperationTypes.RESET) + return client.begin_update(resource_group_name=resource_group_name, + gallery_name=gallery_name, + sharing_update=sharing_update) + + +def sig_shared_image_definition_list(client, location, gallery_unique_name, shared_to=None): + # Keep it here as it will add subscription in the future and we need to set it to None to make it work + if shared_to == 'subscription': + shared_to = None + return client.list(location=location, + gallery_unique_name=gallery_unique_name, + shared_to=shared_to) + + +def sig_shared_image_version_list(client, location, gallery_unique_name, gallery_image_name, shared_to=None): + # Keep it here as it will add subscription in the future and we need to set it to None to make it work + if shared_to == 'subscription': + shared_to = None + return client.list(location=location, gallery_unique_name=gallery_unique_name, + gallery_image_name=gallery_image_name, shared_to=shared_to) + + +def get_gallery_instance(cmd, resource_group_name, gallery_name): + from ._client_factory import cf_vm_cl + client = cf_vm_cl(cmd.cli_ctx) + SelectPermissions = cmd.get_models('SelectPermissions', operation_group='shared_galleries') + return client.galleries.get(resource_group_name, gallery_name, select=SelectPermissions.PERMISSIONS) diff --git a/src/azure-cli/azure/cli/command_modules/vm/gen.zip b/src/azure-cli/azure/cli/command_modules/vm/gen.zip index af56ffe6df5212ed753d3a2987b3effec9f38316..20e3c0f3f2d3a8ac43ad828ce65f3341055e649a 100644 GIT binary patch literal 5436 zcmeHL-D=}T6n1yp()zBjSB1jCDM(&y<))<&Fl;tW(~x8_ak><;K}_UhSsO{C&PYzY zA#czp=vAT6Ui1liQThmdiC*<7dXD}qId;6En`QeWBjlMm=gc|Z%$)gV`g`}^ZZ`P& z_JiLKzx(NvpYi=hgWr#+E=C>eXTIR?GrSN%>d@>77P%} zLVOW}7p5|ilF!kJK}i|INGh`AXO>8U%0bp^b1ijmh~Q#~R`XFsZHOb_iDG+!aM7ls7kWH~w(sfK)?=Y?X!5-3fO0$FjL|vMy(con z_C^!vq4={(iXON=tLCP>z6ZxAsVJMVoM31g;st2Wr7)<|?yOT9RvmYp@S8O@Pf=-_#J3%yNv1|a^SZ_-?-5?l;ADea z^f@=OIc9I<0PAr-Ii;Mxhf}>CCGq-}Ldx%y)j~Xn!Qe}X(snq*DepKkQ4TK2bWW;z zH#tp@*@3Kw8`ID^rNTrnN>y1PUAEJ@ywrN!Ra#WSySiGWRm9wNl}sYiRPI8#EN5N@ z(?JE&t6QeRifUzrg+R_$99;rG&-A+lpY1Pz{*D3a*ZA45AOG^FL3EAZPv`j=?}GLu zur+ZZp*(35%TO3#7z;n=BgB^e=WR1;`H$yqIbD-FBXHtHqR?`D&*HhDhi3(!8{|{s zh^kkJ5{FHb+zzkzzQTxzn#%cM?F3NRUdi%quUy$CUs8F&2D?%-%cd*E*qL0Yjb>kTqehyU`ImhjEs^c$4BD(H`tmNSZa;u zm?Jc9Kr!pC`9;w9rPuR@>M_k)Q^;3Nwo<-4QXHSO|4piuweeE1E?5~W^p^3MoPvdWEI+D|oZ-Tuqgs-tZI~7&+Gg?CYiw!K{CATujOeD26 z&qZ#uQk^6W@dAwg1K}@U9HGCXV98 zwry(kM;&-5l&k6U@a&xb<#~!v={ku}nRTljN`L;SZIwpm)yn~6IV-biCDD)wzIj0N*B))vncy}@4U+`_v!ZseIHX>qwyD{8JQjc delta 165 zcmdm^bxTG%z?+$civa{)d*laAJ-qkNG!_O15SE>sE26N``U~Uce{5@*_(0Ns?#>7i z;b348;n=)`v!7}6Z=Riun}r1gS(t&clhsAk!Kx63OpXz;RY29qz+eit4MtpKnY@S7 beDVho9