Skip to content

Commit 9a648fc

Browse files
haagharoot
andauthored
[vm-repair] Making Public IP as optional (Azure#3755)
* public ipaddress as optional for rescue VMs * public ip address for rescue vm * public ip addr change for rescue vms * Reverted telemetry back to PROD * fixed code style * Add extra space before operator on line 36 as suggested by azdev style check * modified telemetryclient from TEST to PROD * removed duplicate entry for associate_public_ip param * specified specific error type in prompt_public_ip function * included class for testing publicip association on repair vm Co-authored-by: root <root@ubuntu18.vdtdwq5rkvyuhaj2iq0ntqetub.syx.internal.cloudapp.net>
1 parent 2872c55 commit 9a648fc

File tree

5 files changed

+159
-6
lines changed

5 files changed

+159
-6
lines changed

src/vm-repair/azext_vm_repair/_params.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ def load_arguments(self, _):
3030
c.argument('repair_group_name', help='Repair resource group name.')
3131
c.argument('unlock_encrypted_vm', help='Option to auto-unlock encrypted VMs using current subscription auth.')
3232
c.argument('enable_nested', help='enable nested hyperv.')
33+
c.argument('associate_public_ip', help='Option to create repair vm with public ip')
3334

3435
with self.argument_context('vm repair restore') as c:
3536
c.argument('repair_vm_id', help='Repair VM resource id.')

src/vm-repair/azext_vm_repair/_validators.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from re import match, search, findall
99
from knack.log import get_logger
1010
from knack.util import CLIError
11+
from azure.cli.core.azclierror import ValidationError
1112

1213
from azure.cli.command_modules.vm.custom import get_vm, _is_linux_os
1314
from azure.cli.command_modules.resource._client_factory import _resource_client_factory
@@ -85,6 +86,9 @@ def validate_create(cmd, namespace):
8586
_prompt_repair_password(namespace)
8687
# Validate vm password
8788
validate_vm_password(namespace.repair_password, is_linux)
89+
# Prompt input for public ip usage
90+
if not namespace.associate_public_ip:
91+
_prompt_public_ip(namespace)
8892

8993

9094
def validate_restore(cmd, namespace):
@@ -201,6 +205,18 @@ def _prompt_repair_password(namespace):
201205
raise CLIError('Please specify the password parameter in non-interactive mode.')
202206

203207

208+
def _prompt_public_ip(namespace):
209+
from knack.prompting import prompt_y_n, NoTTYException
210+
try:
211+
if prompt_y_n('Does repair vm requires public ip?'):
212+
namespace.associate_public_ip = "yes"
213+
else:
214+
namespace.associate_public_ip = '""'
215+
216+
except NoTTYException:
217+
raise ValidationError('Please specify the associate-public-ip parameter in non-interactive mode.')
218+
219+
204220
def _classic_vm_exists(cmd, resource_group_name, vm_name):
205221
classic_vm_provider = 'Microsoft.ClassicCompute'
206222
vm_resource_type = 'virtualMachines'

src/vm-repair/azext_vm_repair/custom.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
logger = get_logger(__name__)
3939

4040

41-
def create(cmd, vm_name, resource_group_name, repair_password=None, repair_username=None, repair_vm_name=None, copy_disk_name=None, repair_group_name=None, unlock_encrypted_vm=False, enable_nested=False):
41+
def create(cmd, vm_name, resource_group_name, repair_password=None, repair_username=None, repair_vm_name=None, copy_disk_name=None, repair_group_name=None, unlock_encrypted_vm=False, enable_nested=False, associate_public_ip=False):
4242
# Init command helper object
4343
command = command_helper(logger, cmd, 'vm repair create')
4444
# Main command calling block
@@ -65,11 +65,11 @@ def create(cmd, vm_name, resource_group_name, repair_password=None, repair_usern
6565

6666
# Set up base create vm command
6767
if is_linux:
68-
create_repair_vm_command = 'az vm create -g {g} -n {n} --tag {tag} --image {image} --admin-username {username} --admin-password {password} --custom-data {cloud_init_script}' \
69-
.format(g=repair_group_name, n=repair_vm_name, tag=resource_tag, image=os_image_urn, username=repair_username, password=repair_password, cloud_init_script=_get_cloud_init_script())
68+
create_repair_vm_command = 'az vm create -g {g} -n {n} --tag {tag} --image {image} --admin-username {username} --admin-password {password} --public-ip-address {option} --custom-data {cloud_init_script}' \
69+
.format(g=repair_group_name, n=repair_vm_name, tag=resource_tag, image=os_image_urn, username=repair_username, password=repair_password, option=associate_public_ip, cloud_init_script=_get_cloud_init_script())
7070
else:
71-
create_repair_vm_command = 'az vm create -g {g} -n {n} --tag {tag} --image {image} --admin-username {username} --admin-password {password}' \
72-
.format(g=repair_group_name, n=repair_vm_name, tag=resource_tag, image=os_image_urn, username=repair_username, password=repair_password)
71+
create_repair_vm_command = 'az vm create -g {g} -n {n} --tag {tag} --image {image} --admin-username {username} --admin-password {password} --public-ip-address {option}' \
72+
.format(g=repair_group_name, n=repair_vm_name, tag=resource_tag, image=os_image_urn, username=repair_username, password=repair_password, option=associate_public_ip)
7373

7474
# Fetch VM size of repair VM
7575
sku = _fetch_compatible_sku(source_vm, enable_nested)

src/vm-repair/azext_vm_repair/tests/latest/test_repair_commands.py

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,142 @@ def test_vmrepair_LinuxUnmanagedCreateRestore(self, resource_group):
145145
assert source_vm['storageProfile']['osDisk']['vhd']['uri'] == result['copied_disk_uri']
146146

147147

148+
class WindowsManagedDiskCreateRestoreTestwithpublicip(LiveScenarioTest):
149+
150+
@ResourceGroupPreparer(location='westus2')
151+
def test_vmrepair_WinManagedCreateRestore(self, resource_group):
152+
self.kwargs.update({
153+
'vm': 'vm1'
154+
})
155+
156+
# Create test VM
157+
self.cmd('vm create -g {rg} -n {vm} --admin-username azureadmin --image Win2016Datacenter --admin-password !Passw0rd2018')
158+
vms = self.cmd('vm list -g {rg} -o json').get_output_in_json()
159+
# Something wrong with vm create command if it fails here
160+
assert len(vms) == 1
161+
162+
# Test create
163+
result = self.cmd('vm repair create -g {rg} -n {vm} --repair-username azureadmin --repair-password !Passw0rd2018 --associate-public-ip -o json').get_output_in_json()
164+
assert result['status'] == STATUS_SUCCESS, result['error_message']
165+
166+
# Check repair VM
167+
repair_vms = self.cmd('vm list -g {} -o json'.format(result['repair_resource_group'])).get_output_in_json()
168+
assert len(repair_vms) == 1
169+
repair_vm = repair_vms[0]
170+
# Check attached data disk
171+
assert repair_vm['storageProfile']['dataDisks'][0]['name'] == result['copied_disk_name']
172+
173+
# Call Restore
174+
self.cmd('vm repair restore -g {rg} -n {vm} --yes')
175+
176+
# Check swapped OS disk
177+
vms = self.cmd('vm list -g {rg} -o json').get_output_in_json()
178+
source_vm = vms[0]
179+
assert source_vm['storageProfile']['osDisk']['name'] == result['copied_disk_name']
180+
181+
182+
class WindowsUnmanagedDiskCreateRestoreTestwithpublicip(LiveScenarioTest):
183+
184+
@ResourceGroupPreparer(location='westus2')
185+
def test_vmrepair_WinUnmanagedCreateRestore(self, resource_group):
186+
self.kwargs.update({
187+
'vm': 'vm1'
188+
})
189+
190+
# Create test VM
191+
self.cmd('vm create -g {rg} -n {vm} --admin-username azureadmin --image Win2016Datacenter --admin-password !Passw0rd2018 --use-unmanaged-disk')
192+
vms = self.cmd('vm list -g {rg} -o json').get_output_in_json()
193+
# Something wrong with vm create command if it fails here
194+
assert len(vms) == 1
195+
196+
# Test create
197+
result = self.cmd('vm repair create -g {rg} -n {vm} --repair-username azureadmin --repair-password !Passw0rd2018 --associate-public-ip -o json').get_output_in_json()
198+
assert result['status'] == STATUS_SUCCESS, result['error_message']
199+
200+
# Check repair VM
201+
repair_vms = self.cmd('vm list -g {} -o json'.format(result['repair_resource_group'])).get_output_in_json()
202+
assert len(repair_vms) == 1
203+
repair_vm = repair_vms[0]
204+
# Check attached data disk
205+
assert repair_vm['storageProfile']['dataDisks'][0]['name'] == result['copied_disk_name']
206+
207+
# Call Restore
208+
self.cmd('vm repair restore -g {rg} -n {vm} --yes')
209+
210+
# Check swapped OS disk
211+
vms = self.cmd('vm list -g {rg} -o json').get_output_in_json()
212+
source_vm = vms[0]
213+
assert source_vm['storageProfile']['osDisk']['vhd']['uri'] == result['copied_disk_uri']
214+
215+
216+
class LinuxManagedDiskCreateRestoreTestwithpublicip(LiveScenarioTest):
217+
218+
@ResourceGroupPreparer(location='westus2')
219+
def test_vmrepair_LinuxManagedCreateRestore(self, resource_group):
220+
self.kwargs.update({
221+
'vm': 'vm1'
222+
})
223+
224+
# Create test VM
225+
self.cmd('vm create -g {rg} -n {vm} --image UbuntuLTS --admin-username azureadmin --admin-password !Passw0rd2018')
226+
vms = self.cmd('vm list -g {rg} -o json').get_output_in_json()
227+
# Something wrong with vm create command if it fails here
228+
assert len(vms) == 1
229+
230+
# Test create
231+
result = self.cmd('vm repair create -g {rg} -n {vm} --repair-username azureadmin --repair-password !Passw0rd2018 --associate-public-ip -o json').get_output_in_json()
232+
assert result['status'] == STATUS_SUCCESS, result['error_message']
233+
234+
# Check repair VM
235+
repair_vms = self.cmd('vm list -g {} -o json'.format(result['repair_resource_group'])).get_output_in_json()
236+
assert len(repair_vms) == 1
237+
repair_vm = repair_vms[0]
238+
# Check attached data disk
239+
assert repair_vm['storageProfile']['dataDisks'][0]['name'] == result['copied_disk_name']
240+
241+
# Call Restore
242+
self.cmd('vm repair restore -g {rg} -n {vm} --yes')
243+
244+
# Check swapped OS disk
245+
vms = self.cmd('vm list -g {rg} -o json').get_output_in_json()
246+
source_vm = vms[0]
247+
assert source_vm['storageProfile']['osDisk']['name'] == result['copied_disk_name']
248+
249+
250+
class LinuxUnmanagedDiskCreateRestoreTestwithpublicip(LiveScenarioTest):
251+
252+
@ResourceGroupPreparer(location='westus2')
253+
def test_vmrepair_LinuxUnmanagedCreateRestore(self, resource_group):
254+
self.kwargs.update({
255+
'vm': 'vm1'
256+
})
257+
258+
# Create test VM
259+
self.cmd('vm create -g {rg} -n {vm} --image UbuntuLTS --admin-username azureadmin --admin-password !Passw0rd2018 --use-unmanaged-disk')
260+
vms = self.cmd('vm list -g {rg} -o json').get_output_in_json()
261+
# Something wrong with vm create command if it fails here
262+
assert len(vms) == 1
263+
264+
# Test create
265+
result = self.cmd('vm repair create -g {rg} -n {vm} --repair-username azureadmin --repair-password !Passw0rd2018 --associate-public-ip -o json').get_output_in_json()
266+
assert result['status'] == STATUS_SUCCESS, result['error_message']
267+
268+
# Check repair VM
269+
repair_vms = self.cmd('vm list -g {} -o json'.format(result['repair_resource_group'])).get_output_in_json()
270+
assert len(repair_vms) == 1
271+
repair_vm = repair_vms[0]
272+
# Check attached data disk
273+
assert repair_vm['storageProfile']['dataDisks'][0]['name'] == result['copied_disk_name']
274+
275+
# Call Restore
276+
self.cmd('vm repair restore -g {rg} -n {vm} --yes')
277+
278+
# Check swapped OS disk
279+
vms = self.cmd('vm list -g {rg} -o json').get_output_in_json()
280+
source_vm = vms[0]
281+
assert source_vm['storageProfile']['osDisk']['vhd']['uri'] == result['copied_disk_uri']
282+
283+
148284
class WindowsSinglepassKekEncryptedManagedDiskCreateRestoreTest(LiveScenarioTest):
149285

150286
@ResourceGroupPreparer(location='westus2')

src/vm-repair/setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
name='vm-repair',
3434
version=VERSION,
3535
description='Auto repair commands to fix VMs.',
36-
long_description='VM repair command will enable Azure users to self-repair non-bootable VMs by copying the source VM\'s OS disk and attaching it to a newly created repair VM.'+ '\n\n' + HISTORY,
36+
long_description='VM repair command will enable Azure users to self-repair non-bootable VMs by copying the source VM\'s OS disk and attaching it to a newly created repair VM.' + '\n\n' + HISTORY,
3737
license='MIT',
3838
author='Microsoft Corporation',
3939
author_email='[email protected]',

0 commit comments

Comments
 (0)