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
1 change: 1 addition & 0 deletions src/azure-cli/HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ Release History

* vm create: Add warning when specifying accelerated networking and an existing NIC together.
* vm create: Add --vmss to specify an existing virtual machine scale set that the virtual machine should be assigned to.
* vm/vmss create: Add a local copy of image alias file so that it can be accessed in a restricted network environment.
* vmss create: Add --orchestration-mode to specify how virtual machines are managed by the scale set.
* vm/vmss update: Add --ultra-ssd-enabled to allow updating ultra SSD setting.
* [BREAKING CHANGE] vm extension set: Fix bug where users could not set an extension on a VM with --ids.
Expand Down
22 changes: 17 additions & 5 deletions src/azure-cli/azure/cli/command_modules/vm/_actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,15 @@
import json

from knack.util import CLIError
from knack.log import get_logger

from azure.cli.core.commands.parameters import get_one_of_subscription_locations
from azure.cli.core.commands.arm import resource_exists

from ._client_factory import _compute_client_factory

logger = get_logger(__name__)


def _resource_not_exists(cli_ctx, resource_type):
def _handle_resource_not_exists(namespace):
Expand Down Expand Up @@ -79,10 +82,19 @@ def load_images_from_aliases_doc(cli_ctx, publisher=None, offer=None, sku=None):
raise CLIError("'endpoint_vm_image_alias_doc' isn't configured. Please invoke 'az cloud update' to configure "
"it or use '--all' to retrieve images from server")
# under hack mode(say through proxies with unsigned cert), opt out the cert verification
response = requests.get(target_url, verify=(not should_disable_connection_verify()))
if response.status_code != 200:
raise CLIError("Failed to retrieve image alias doc '{}'. Error: '{}'".format(target_url, response))
dic = json.loads(response.content.decode())
from azure.cli.command_modules.vm._alias import alias_json
try:
response = requests.get(target_url, verify=(not should_disable_connection_verify()))
if response.status_code == 200:
dic = json.loads(response.content.decode())
else:
logger.warning("Failed to retrieve image alias doc '%s'. Error: '%s'. Use local copy instead.",
target_url, response)
dic = json.loads(alias_json)
except requests.exceptions.ConnectionError:
logger.warning("Failed to retrieve image alias doc '%s'. Error: 'ConnectionError'. Use local copy instead.",
target_url)
dic = json.loads(alias_json)
try:
all_images = []
result = (dic['outputs']['aliases']['value'])
Expand All @@ -101,7 +113,7 @@ def load_images_from_aliases_doc(cli_ctx, publisher=None, offer=None, sku=None):
_matched(sku, i['sku']))]
return all_images
except KeyError:
raise CLIError('Could not retrieve image list from {}'.format(target_url))
raise CLIError('Could not retrieve image list from {} or local copy'.format(target_url))


def load_extension_images_thru_services(cli_ctx, publisher, name, version, location,
Expand Down
101 changes: 101 additions & 0 deletions src/azure-cli/azure/cli/command_modules/vm/_alias.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
# --------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
# --------------------------------------------------------------------------------------------

# Alias for image
# https://github.com/Azure/azure-rest-api-specs/blob/master/arm-compute/quickstart-templates/aliases.json

alias_json = """
{
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json",
"contentVersion": "1.0.0.0",
"parameters": {},
"variables": {},
"resources": [],
"outputs": {
"aliases": {
"type": "object",
"value": {
"Linux": {
"CentOS": {
"publisher": "OpenLogic",
"offer": "CentOS",
"sku": "7.5",
"version": "latest"
},
"CoreOS": {
"publisher": "CoreOS",
"offer": "CoreOS",
"sku": "Stable",
"version": "latest"
},
"Debian": {
"publisher": "Debian",
"offer": "debian-10",
"sku": "10",
"version": "latest"
},
"openSUSE-Leap": {
"publisher": "SUSE",
"offer": "openSUSE-Leap",
"sku": "42.3",
"version": "latest"
},
"RHEL": {
"publisher": "RedHat",
"offer": "RHEL",
"sku": "7-LVM",
"version": "latest"
},
"SLES": {
"publisher": "SUSE",
"offer": "SLES",
"sku": "15",
"version": "latest"
},
"UbuntuLTS": {
"publisher": "Canonical",
"offer": "UbuntuServer",
"sku": "18.04-LTS",
"version": "latest"
}
},
"Windows": {
"Win2019Datacenter": {
"publisher": "MicrosoftWindowsServer",
"offer": "WindowsServer",
"sku": "2019-Datacenter",
"version": "latest"
},
"Win2016Datacenter": {
"publisher": "MicrosoftWindowsServer",
"offer": "WindowsServer",
"sku": "2016-Datacenter",
"version": "latest"
},
"Win2012R2Datacenter": {
"publisher": "MicrosoftWindowsServer",
"offer": "WindowsServer",
"sku": "2012-R2-Datacenter",
"version": "latest"
},
"Win2012Datacenter": {
"publisher": "MicrosoftWindowsServer",
"offer": "WindowsServer",
"sku": "2012-Datacenter",
"version": "latest"
},
"Win2008R2SP1": {
"publisher": "MicrosoftWindowsServer",
"offer": "WindowsServer",
"sku": "2008-R2-SP1",
"version": "latest"
}
}
}
}
}
}

"""
5 changes: 3 additions & 2 deletions src/azure-cli/azure/cli/command_modules/vm/_validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,7 @@ def _parse_image_argument(cmd, namespace):
from azure.cli.command_modules.vm._actions import load_images_from_aliases_doc
import requests
try:
images = None
images = load_images_from_aliases_doc(cmd.cli_ctx)
matched = next((x for x in images if x['urnAlias'].lower() == namespace.image.lower()), None)
if matched:
Expand All @@ -280,8 +281,8 @@ def _parse_image_argument(cmd, namespace):
'VHD blob URI, or pick an image from {}.\nSee vm create -h for more information ' \
'on specifying an image.'.format(namespace.image, [x['urnAlias'] for x in images])
else:
err = 'Failed to connect to remote source of image aliases. Invalid image "{}". Use a ' \
'valid image URN, custom image name, custom image id, or VHD blob URI.\nSee vm ' \
err = 'Failed to connect to remote source of image aliases or find a local copy. Invalid image "{}". ' \
'Use a valid image URN, custom image name, custom image id, or VHD blob URI.\nSee vm ' \
'create -h for more information on specifying an image.'.format(namespace.image)
raise CLIError(err)

Expand Down