Skip to content

Commit

Permalink
{vm-repair} Changing default windows image from the old 2016 to the 2…
Browse files Browse the repository at this point in the history
…022 image (#8046)
  • Loading branch information
Sandido authored Nov 1, 2024
1 parent a90f51e commit cdc2dc0
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 8 deletions.
5 changes: 5 additions & 0 deletions src/vm-repair/HISTORY.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@

Release History
===============

2.0.0
++++++
Changed default VM image to 2022-datacenter-smalldisk for better default security.

1.1.1
++++++
Migrated VM Repair off of the `msrestazure` API to `azure.core` and `azure.mgmt` APIs.
Expand Down
5 changes: 4 additions & 1 deletion src/vm-repair/azext_vm_repair/custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
_list_resource_ids_in_rg,
_get_repair_resource_tag,
_fetch_compatible_windows_os_urn,
_fetch_compatible_windows_os_urn_v2,
_fetch_run_script_map,
_fetch_run_script_path,
_process_ps_parameters,
Expand Down Expand Up @@ -92,11 +93,13 @@ def create(cmd, vm_name, resource_group_name, repair_password=None, repair_usern
else:
os_image_urn = _select_distro_linux(distro)
else:
os_type = 'Windows'
if encrypt_recovery_key:
# Call the new URN matching logic.
os_image_urn = _fetch_compatible_windows_os_urn_v2(source_vm)
else:
# Use the old default to 2022 image logic.
os_image_urn = _fetch_compatible_windows_os_urn(source_vm)
os_type = 'Windows'

# Set public IP address for repair VM
public_ip_name = _make_public_ip_name(repair_vm_name, associate_public_ip)
Expand Down
9 changes: 4 additions & 5 deletions src/vm-repair/azext_vm_repair/repair_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -478,7 +478,7 @@ def _unlock_mount_windows_encrypted_disk(repair_vm_name, repair_group_name, encr

def _fetch_compatible_windows_os_urn(source_vm):
location = source_vm.location
fetch_urn_command = 'az vm image list -s "2016-Datacenter" -f WindowsServer -p MicrosoftWindowsServer -l {loc} --verbose --all --query "[?sku==\'2016-Datacenter\'].urn | reverse(sort(@))" -o json'.format(loc=location)
fetch_urn_command = 'az vm image list -s "2022-datacenter-smalldisk" -f WindowsServer -p MicrosoftWindowsServer -l {loc} --verbose --all --query "[?sku==\'2022-datacenter-smalldisk\'].urn | reverse(sort(@))" -o json'.format(loc=location)
logger.info('Fetching compatible Windows OS images from gallery...')
urns = loads(_call_az_command(fetch_urn_command))

Expand All @@ -491,7 +491,7 @@ def _fetch_compatible_windows_os_urn(source_vm):
os_image_ref = source_vm.storage_profile.image_reference
if os_image_ref and isinstance(os_image_ref.version, str) and os_image_ref.version in urns[0]:
if len(urns) < 2:
logger.debug('Avoiding Win2016 latest image due to expected disk collision. But no other image available.')
logger.debug('Avoiding Win2022-datacenter-smalldisk latest image due to expected disk collision. But no other image available.')
raise WindowsOsNotAvailableError()
logger.debug('Returning Urn 1 to avoid disk collision error: %s', urns[1])
return urns[1]
Expand Down Expand Up @@ -733,15 +733,14 @@ def _unlock_encrypted_vm_run(repair_vm_name, repair_group_name, is_linux, encryp

def _create_repair_vm(copy_disk_id, create_repair_vm_command, repair_password, repair_username, fix_uuid=False):

# logging all parameters of the function individually
# logging parameters of the function individually
logger.info('Creating repair VM with command: {}'.format(create_repair_vm_command))
logger.info('copy_disk_id: {}'.format(copy_disk_id))
logger.info('repair_password: {}'.format(repair_password))
logger.info('repair_username: {}'.format(repair_username))
logger.info('fix_uuid: {}'.format(fix_uuid))

if not fix_uuid:
create_repair_vm_command += ' --attach-data-disks {id}'.format(id=copy_disk_id)

logger.info('Validating VM template before continuing...')
_call_az_command(create_repair_vm_command + ' --validate', secure_params=[repair_password, repair_username])
logger.info('Creating repair VM...')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1070,4 +1070,62 @@ def test_vmrepair_WindowsPublicIPWithParameter(self, resource_group):
assert result_run['status'] == STATUS_SUCCESS, result_run['error_message']

# Call Restore
self.cmd('vm repair restore -g {rg} -n {vm} --yes')
self.cmd('vm repair restore -g {rg} -n {vm} --yes')

@pytest.mark.winDefaultGen1Image
class WindowsDefaultGen1Image(LiveScenarioTest):

@ResourceGroupPreparer(location='westus2')
def test_vmrepair_DefaultGen1Image(self, resource_group):
import uuid
import secrets
import string
base_password = "Passw0rd2024"
guid_suffix = str(uuid.uuid4())
secure_password = base_password + guid_suffix
username_length = 8
secure_username = ''.join(secrets.choice(string.ascii_letters + string.digits) for _ in range(username_length))
self.kwargs.update({
'vm': 'vm1',
'admin_password': secure_password,
'admin_username': secure_username
})

# Use current default sku for Windows scenario.
defaultSku = "2022-datacenter-smalldisk"
# Create test VM
self.cmd('vm create -g {rg} -n {vm} --admin-username {admin_username} --admin-password {admin_password} --image MicrosoftWindowsServer:windowsserver:2019-datacenter-gs:latest')
vms = self.cmd('vm list -g {rg} -o json').get_output_in_json()
# Something wrong with vm create command if it fails here
assert len(vms) == 1

# Create Repair VM
repair_vm = self.cmd('vm repair create -g {rg} -n {vm} --repair-username {admin_username} --repair-password {admin_password} --yes -o json').get_output_in_json()
assert repair_vm['status'] == STATUS_SUCCESS, repair_vm['error_message']
# Check repair VM
self.kwargs.update({
'vm': 'vm1',
'admin_password': secure_password,
'admin_username': secure_username,
'repair_resource_group': repair_vm['repair_resource_group']
})
repair_vms = self.cmd('vm list -g {repair_resource_group} -o json').get_output_in_json()
assert len(repair_vms) == 1
repair_vm = repair_vms[0]
repair_vm_id = repair_vm['id']
# Verify the image sku is the default sku
image_info = repair_vm['storageProfile']['imageReference']
assert image_info['sku'] == defaultSku

self.kwargs.update({
'vm': 'vm1',
'admin_password': secure_password,
'admin_username': secure_username,
'repair_vm_id': repair_vm_id
})
# Run a script for testing repair-vm-id
result_run = self.cmd('vm repair run -g {rg} -n {vm} --run-id win-hello-world --repair-vm-id {repair_vm_id} --run-on-repair -o json').get_output_in_json()
assert result_run['status'] == STATUS_SUCCESS, result_run['error_message']

# Call Restore
self.cmd('vm repair restore -g {rg} -n {vm} --yes')
2 changes: 1 addition & 1 deletion src/vm-repair/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from codecs import open
from setuptools import setup, find_packages

VERSION = "1.1.1"
VERSION = "2.0.0"

CLASSIFIERS = [
'Development Status :: 4 - Beta',
Expand Down

0 comments on commit cdc2dc0

Please sign in to comment.