Skip to content
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
3 changes: 1 addition & 2 deletions src/azure-cli-core/azure/cli/core/profiles/_shared.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,7 @@ def default_api_version(self):
ResourceType.MGMT_COMPUTE: SDKProfile('2019-03-01', {
'resource_skus': '2017-09-01',
'disks': '2018-09-30',
'snapshots': '2018-09-30',
'images': '2018-10-01'
'snapshots': '2018-09-30'
}),
ResourceType.MGMT_RESOURCE_FEATURES: '2015-12-01',
ResourceType.MGMT_RESOURCE_LINKS: '2016-09-01',
Expand Down
2 changes: 1 addition & 1 deletion src/command_modules/azure-cli-acs/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
DEPENDENCIES = [
'azure-mgmt-authorization==0.50.0',
'azure-mgmt-containerservice==5.1.0',
'azure-mgmt-compute==4.6.1',
'azure-mgmt-compute==5.0.0',
'azure-graphrbac==0.60.0',
'azure-cli-core',
'paramiko>=2.0.8',
Expand Down
2 changes: 1 addition & 1 deletion src/command_modules/azure-cli-servicefabric/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
'azure-graphrbac==0.60.0',
'azure-keyvault==1.1.0',
'azure-mgmt-network==2.6.0',
'azure-mgmt-compute==4.6.1',
'azure-mgmt-compute==5.0.0',
'azure-mgmt-storage==3.1.1',
'azure-mgmt-servicefabric==0.2.0',
'azure-mgmt-keyvault==1.1.0',
Expand Down
3 changes: 3 additions & 0 deletions src/command_modules/azure-cli-vm/HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ Release History
* vmss update: add `--protect-from-scale-in` and `--protect-from-scale-set-actions` to enable updates to the protection policy of VMSS VM instances.
* vmss update: add `--instance-id` to enable generic update of VMSS VM instances.
* vmss wait: add `--instance-id`.
* [new command group] ppg: add `ppg create / delete / list / show / update` for managing Proximity Placement Groups.
* ppg: add `--ppg` to `vm create`, `vmss create` and `vm availability-set create`
* image create: expose `--hyper-v-generation` parameter.

2.2.19
++++++
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,3 +96,7 @@ def cf_gallery_images(cli_ctx, _):

def cf_gallery_image_versions(cli_ctx, _):
return _compute_client_factory(cli_ctx).gallery_image_versions


def cf_proximity_placement_groups(cli_ctx, _):
return _compute_client_factory(cli_ctx).proximity_placement_groups
Original file line number Diff line number Diff line change
Expand Up @@ -1922,3 +1922,28 @@
- name: Place the CLI in a waiting state until the VMSS instance has been updated.
text: az vmss wait --updated --instance-id 1 --name MyScaleSet --resource-group MyResourceGroup
"""

helps['ppg'] = """
type: group
short-summary: Manage Proximity Placement Groups
"""

helps['ppg create'] = """
type: command
short-summary: Create a proximity placement group
"""

helps['ppg show'] = """
type: command
short-summary: Get a proximity placement group
"""

helps['ppg list'] = """
type: command
short-summary: List proximity placement groups
"""

helps['ppg update'] = """
type: command
short-summary: Update a proximity placement group
"""
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,18 @@
get_urn_aliases_completion_list, get_vm_size_completion_list, get_vm_run_command_completion_list)
from azure.cli.command_modules.vm._validators import (
validate_nsg_name, validate_vm_nics, validate_vm_nic, validate_vm_disk, validate_vmss_disk,
validate_asg_names_or_ids, validate_keyvault, process_gallery_image_version_namespace)
validate_asg_names_or_ids, validate_keyvault, validate_proximity_placement_group,
process_gallery_image_version_namespace)

from ._vm_utils import MSI_LOCAL_ID


# pylint: disable=too-many-statements, too-many-branches, too-many-locals
def load_arguments(self, _):
StorageAccountTypes, UpgradeMode, CachingTypes = self.get_models('StorageAccountTypes', 'UpgradeMode', 'CachingTypes')
OperatingSystemTypes = self.get_models('OperatingSystemTypes')
# Model imports
StorageAccountTypes, DiskStorageAccountTypes, SnapshotStorageAccountTypes = self.get_models('StorageAccountTypes', 'DiskStorageAccountTypes', 'SnapshotStorageAccountTypes')
UpgradeMode, CachingTypes, OperatingSystemTypes = self.get_models('UpgradeMode', 'CachingTypes', 'OperatingSystemTypes')
ProximityPlacementGroupType, HyperVGenerationTypes, HyperVGeneration = self.get_models('ProximityPlacementGroupType', 'HyperVGenerationTypes', 'HyperVGeneration')

# REUSABLE ARGUMENT DEFINITIONS
name_arg_type = CLIArgumentType(options_list=['--name', '-n'], metavar='NAME')
Expand All @@ -46,17 +50,33 @@ def load_arguments(self, _):

extension_instance_name_type = CLIArgumentType(help="Name of the vm's instance of the extension. Default: name of the extension.")

if StorageAccountTypes:
disk_sku = CLIArgumentType(arg_type=get_enum_type(StorageAccountTypes))
# StorageAccountTypes renamed to DiskStorageAccountTypes in 2018_06_01 of azure-mgmt-compute
DiskStorageAccountTypes = DiskStorageAccountTypes or StorageAccountTypes

if DiskStorageAccountTypes:
disk_sku = CLIArgumentType(arg_type=get_enum_type(DiskStorageAccountTypes))
else:
# StorageAccountTypes introduced in api version 2016_04_30_preview of Resource.MGMT.Compute package..
# However, 2017-03-09-profile targets version 2016-03-30 of compute package.
disk_sku = CLIArgumentType(arg_type=get_enum_type(['Premium_LRS', 'Standard_LRS']))

if SnapshotStorageAccountTypes:
snapshot_sku = CLIArgumentType(arg_type=get_enum_type(SnapshotStorageAccountTypes))
else:
# SnapshotStorageAccountTypes introduced in api version 2018_04_01 of Resource.MGMT.Compute package..
# However, 2017-03-09-profile targets version 2016-03-30 of compute package.
snapshot_sku = CLIArgumentType(arg_type=get_enum_type(['Premium_LRS', 'Standard_LRS']))

# special case for `network nic scale-set list` command alias
with self.argument_context('network nic scale-set list') as c:
c.argument('virtual_machine_scale_set_name', options_list=['--vmss-name'], completer=get_resource_name_completion_list('Microsoft.Compute/virtualMachineScaleSets'), id_part='name')

HyperVGenerationTypes = HyperVGenerationTypes or HyperVGeneration
if HyperVGenerationTypes:
hyper_v_gen_sku = CLIArgumentType(arg_type=get_enum_type(HyperVGenerationTypes, default="V1"))
else:
hyper_v_gen_sku = CLIArgumentType(arg_type=get_enum_type(["V1", "V2"], default="V1"))

# region MixedScopes
for scope in ['vm', 'disk', 'snapshot', 'image', 'sig']:
with self.argument_context(scope) as c:
Expand All @@ -72,7 +92,9 @@ def load_arguments(self, _):
c.argument('access_level', arg_type=get_enum_type(['Read', 'Write']), default='Read', help='access level')
c.argument('for_upload', arg_type=get_three_state_flag(),
help='Create the {0} for uploading blobs later on through storage commands. Run "az {0} grant-access --access-level Write" to retrieve the {0}\'s SAS token.'.format(scope))
c.argument('hyper_v_generation', help='The hypervisor generation of the Virtual Machine. Applicable to OS disks only. Possible values include: "V1", "V2"')
c.argument('hyper_v_generation', arg_type=hyper_v_gen_sku, help='The hypervisor generation of the Virtual Machine. Applicable to OS disks only.')
else:
c.ignore('access_level', 'for_upload', 'hyper_v_generation')

for scope in ['disk create', 'snapshot create']:
with self.argument_context(scope) as c:
Expand All @@ -94,10 +116,7 @@ def load_arguments(self, _):
with self.argument_context('snapshot', resource_type=ResourceType.MGMT_COMPUTE, operation_group='snapshots') as c:
c.argument('snapshot_name', existing_snapshot_name, id_part='name', completer=get_resource_name_completion_list('Microsoft.Compute/snapshots'))
c.argument('name', arg_type=name_arg_type)
if self.supported_api_version(min_api='2018-04-01', operation_group='snapshots'):
c.argument('sku', arg_type=get_enum_type(['Premium_LRS', 'Standard_LRS', 'Standard_ZRS']))
else:
c.argument('sku', arg_type=get_enum_type(['Premium_LRS', 'Standard_LRS']))
c.argument('sku', arg_type=snapshot_sku)
# endregion

# region Images
Expand All @@ -115,6 +134,7 @@ def load_arguments(self, _):
'Default is false. Zone resilient images can be created only in regions that provide Zone Redundant Storage')
c.argument('storage_sku', arg_type=disk_sku, help='The SKU of the storage account with which to create the VM image. Unused if source VM is specified.')
c.argument('os_disk_caching', arg_type=get_enum_type(CachingTypes), help="Storage caching type for the image's OS disk.")
c.argument('hyper_v_generation', arg_type=hyper_v_gen_sku, min_api="2019-03-01", help='The hypervisor generation of the Virtual Machine created from the image.')
c.ignore('source_virtual_machine', 'os_blob_uri', 'os_disk', 'os_snapshot', 'data_blob_uris', 'data_disks', 'data_snapshots')
# endregion

Expand Down Expand Up @@ -444,8 +464,8 @@ def load_arguments(self, _):
c.argument('authentication_type', help='Type of authentication to use with the VM. Defaults to password for Windows and SSH public key for Linux. "all" enables both ssh and password authentication. ', arg_type=get_enum_type(['ssh', 'password', 'all']))

with self.argument_context(scope, arg_group='Storage') as c:
if StorageAccountTypes:
allowed_values = ", ".join([sku.value for sku in StorageAccountTypes])
if DiskStorageAccountTypes:
allowed_values = ", ".join([sku.value for sku in DiskStorageAccountTypes])
else:
allowed_values = ", ".join(['Premium_LRS', 'Standard_LRS'])

Expand Down Expand Up @@ -613,3 +633,17 @@ def load_arguments(self, _):
'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)
# endregion

# region Proximity Placement Group
with self.argument_context('ppg', min_api='2018-04-01') as c:
c.argument('proximity_placement_group_name', arg_type=name_arg_type, help="The name of the proximity placement group.")

with self.argument_context('ppg create', min_api='2018-04-01') as c:
c.argument('ppg_type', options_list=['--type', '-t'], arg_type=get_enum_type(ProximityPlacementGroupType), help="The type of the proximity placement group.")
c.argument('tags', tags_type)

for scope, item in [('vm create', 'VM'), ('vmss create', 'VMSS'), ('vm availability-set create', 'availability set')]:
with self.argument_context(scope, min_api='2018-04-01') as c:
c.argument('proximity_placement_group', options_list=['--ppg'], help="The name or ID of the proximity placement group the {} should be associated with.".format(item),
validator=validate_proximity_placement_group) # only availability set does not have a command level validator, so this should be added.
# endregion
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ def build_vm_resource( # pylint: disable=too-many-locals
image_reference=None, os_disk_name=None, custom_image_os_type=None, authentication_type=None,
os_publisher=None, os_offer=None, os_sku=None, os_version=None, os_vhd_uri=None,
attach_os_disk=None, os_disk_size_gb=None, custom_data=None, secrets=None, license_type=None, zone=None,
disk_info=None, boot_diagnostics_storage_uri=None, ultra_ssd_enabled=None):
disk_info=None, boot_diagnostics_storage_uri=None, ultra_ssd_enabled=None, proximity_placement_group=None):

os_caching = disk_info['os'].get('caching')

Expand Down Expand Up @@ -389,6 +389,9 @@ def _build_storage_profile():
if ultra_ssd_enabled is not None:
vm_properties['additionalCapabilities'] = {'ultraSSDEnabled': ultra_ssd_enabled}

if proximity_placement_group:
vm_properties['proximityPlacementGroup'] = {'id': proximity_placement_group}

vm = {
'apiVersion': cmd.get_api_version(ResourceType.MGMT_COMPUTE, operation_group='virtual_machines'),
'type': 'Microsoft.Compute/virtualMachines',
Expand Down Expand Up @@ -616,7 +619,7 @@ def build_vmss_resource(cmd, name, naming_prefix, location, tags, overprovision,
backend_address_pool_id=None, inbound_nat_pool_id=None, health_probe=None,
single_placement_group=None, platform_fault_domain_count=None, custom_data=None,
secrets=None, license_type=None, zones=None, priority=None, eviction_policy=None,
application_security_groups=None, ultra_ssd_enabled=None):
application_security_groups=None, ultra_ssd_enabled=None, proximity_placement_group=None):

# Build IP configuration
ip_configuration = {
Expand Down Expand Up @@ -782,6 +785,9 @@ def build_vmss_resource(cmd, name, naming_prefix, location, tags, overprovision,
if ultra_ssd_enabled is not None:
vmss_properties['virtualMachineProfile']['additionalCapabilities'] = {'ultraSSDEnabled': ultra_ssd_enabled}

if proximity_placement_group:
vmss_properties['proximityPlacementGroup'] = {'id': proximity_placement_group}

vmss = {
'type': 'Microsoft.Compute/virtualMachineScaleSets',
'name': name,
Expand All @@ -800,8 +806,8 @@ def build_vmss_resource(cmd, name, naming_prefix, location, tags, overprovision,
return vmss


def build_av_set_resource(cmd, name, location, tags,
platform_update_domain_count, platform_fault_domain_count, unmanaged):
def build_av_set_resource(cmd, name, location, tags, platform_update_domain_count,
platform_fault_domain_count, unmanaged, proximity_placement_group=None):
av_set = {
'type': 'Microsoft.Compute/availabilitySets',
'name': name,
Expand All @@ -822,4 +828,7 @@ def build_av_set_resource(cmd, name, location, tags,
if platform_update_domain_count is not None:
av_set['properties']['platformUpdateDomainCount'] = platform_update_domain_count

if proximity_placement_group:
av_set['properties']['proximityPlacementGroup'] = {'id': proximity_placement_group}

return av_set
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,21 @@ def validate_keyvault(cmd, namespace):
'vaults', 'Microsoft.KeyVault')


def validate_proximity_placement_group(cmd, namespace):
from msrestazure.tools import parse_resource_id

if namespace.proximity_placement_group:
namespace.proximity_placement_group = _get_resource_id(cmd.cli_ctx, namespace.proximity_placement_group,
namespace.resource_group_name,
'proximityPlacementGroups', 'Microsoft.Compute')

parsed = parse_resource_id(namespace.proximity_placement_group)
rg, name = parsed['resource_group'], parsed['name']

if not check_existence(cmd.cli_ctx, name, rg, 'Microsoft.Compute', 'proximityPlacementGroups'):
raise CLIError("Proximity Placement Group '{}' does not exist.".format(name))


def process_vm_secret_format(cmd, namespace):
from msrestazure.tools import is_valid_resource_id
from azure.cli.core._output import (get_output_format, set_output_format)
Expand Down Expand Up @@ -1027,6 +1042,8 @@ def process_vm_create_namespace(cmd, namespace):
_validate_vm_create_nics(cmd, namespace)
_validate_vm_vmss_accelerated_networking(cmd.cli_ctx, namespace)
_validate_vm_vmss_create_auth(namespace)
validate_proximity_placement_group(cmd, namespace)

if namespace.secrets:
_validate_secrets(namespace.secrets, namespace.os_type)
if namespace.license_type and namespace.os_type.lower() != 'windows':
Expand Down Expand Up @@ -1212,6 +1229,7 @@ def process_vmss_create_namespace(cmd, namespace):
_validate_vm_vmss_accelerated_networking(cmd.cli_ctx, namespace)
_validate_vm_vmss_create_auth(namespace)
_validate_vm_vmss_msi(cmd, namespace)
validate_proximity_placement_group(cmd, namespace)

if namespace.secrets:
_validate_secrets(namespace.secrets, namespace.os_type)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
cf_vm_sizes, cf_disks, cf_snapshots,
cf_images, cf_run_commands,
cf_rolling_upgrade_commands, cf_galleries,
cf_gallery_images, cf_gallery_image_versions)
cf_gallery_images, cf_gallery_image_versions,
cf_proximity_placement_groups)
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,
Expand Down Expand Up @@ -131,6 +132,10 @@ def load_command_table(self, _):
client_factory=cf_gallery_image_versions,
)

compute_proximity_placement_groups_sdk = CliCommandType(
operations_tmpl='azure.mgmt.compute.operations#ProximityPlacementGroupsOperations.{}'
)

with self.command_group('disk', compute_disk_sdk, operation_group='disks', min_api='2017-03-30') as g:
g.custom_command('create', 'create_managed_disk', supports_no_wait=True, table_transformer=transform_disk_show_table_output, validator=process_disk_or_snapshot_create_namespace)
g.command('delete', 'delete', supports_no_wait=True, confirmation=True)
Expand Down Expand Up @@ -350,3 +355,10 @@ def load_command_table(self, _):
g.custom_command('create', 'create_image_version', supports_no_wait=True)
g.generic_update_command('update', setter_arg_name='gallery_image_version', custom_func_name='update_image_version', supports_no_wait=True)
g.wait_command('wait')

with self.command_group('ppg', compute_proximity_placement_groups_sdk, min_api='2018-04-01', client_factory=cf_proximity_placement_groups) as g:
g.command('show', 'get')
g.custom_command('create', 'create_proximity_placement_group')
g.custom_command('list', 'list_proximity_placement_groups')
g.generic_update_command('update')
g.command('delete', 'delete')
Loading