Various fixes to azure_rm_virtualmachine for managed disks and allocated. (#30450)

* fixes #30194
* fixes #30193
* fixes #29662
* fixes #28859
pull/30452/head
Matt Davis 7 years ago committed by GitHub
parent 6b5b465125
commit c12c7a72ed

@ -71,8 +71,7 @@ options:
vm_size: vm_size:
description: description:
- A valid Azure VM size value. For example, 'Standard_D4'. The list of choices varies depending on the - A valid Azure VM size value. For example, 'Standard_D4'. The list of choices varies depending on the
subscription and location. Check your subscription for available choices. subscription and location. Check your subscription for available choices. Required when creating a VM.
required: true
admin_username: admin_username:
description: description:
- Admin username used to access the host after it is created. Required when creating a VM. - Admin username used to access the host after it is created. Required when creating a VM.
@ -582,7 +581,7 @@ class AzureRMVirtualMachine(AzureRMModuleBase):
state=dict(choices=['present', 'absent'], default='present', type='str'), state=dict(choices=['present', 'absent'], default='present', type='str'),
location=dict(type='str'), location=dict(type='str'),
short_hostname=dict(type='str'), short_hostname=dict(type='str'),
vm_size=dict(type='str', required=True), vm_size=dict(type='str'),
admin_username=dict(type='str'), admin_username=dict(type='str'),
admin_password=dict(type='str', no_log=True), admin_password=dict(type='str', no_log=True),
ssh_password_enabled=dict(type='bool', default=True), ssh_password_enabled=dict(type='bool', default=True),
@ -761,7 +760,7 @@ class AzureRMVirtualMachine(AzureRMModuleBase):
changed = True changed = True
vm_dict['properties']['osProfile']['computerName'] = self.short_hostname vm_dict['properties']['osProfile']['computerName'] = self.short_hostname
if self.started and vm_dict['powerstate'] != 'running': if self.started and vm_dict['powerstate'] not in ['starting', 'running'] and self.allocated:
self.log("CHANGED: virtual machine {0} not running and requested state 'running'".format(self.name)) self.log("CHANGED: virtual machine {0} not running and requested state 'running'".format(self.name))
changed = True changed = True
powerstate_change = 'poweron' powerstate_change = 'poweron'
@ -770,7 +769,7 @@ class AzureRMVirtualMachine(AzureRMModuleBase):
.format(self.name, vm_dict['powerstate'])) .format(self.name, vm_dict['powerstate']))
changed = True changed = True
powerstate_change = 'restarted' powerstate_change = 'restarted'
elif self.state == 'present' and not self.allocated and vm_dict['powerstate'] != 'deallocated': elif self.state == 'present' and not self.allocated and vm_dict['powerstate'] not in ['deallocated', 'deallocating']:
self.log("CHANGED: virtual machine {0} {1} and requested state 'deallocated'" self.log("CHANGED: virtual machine {0} {1} and requested state 'deallocated'"
.format(self.name, vm_dict['powerstate'])) .format(self.name, vm_dict['powerstate']))
changed = True changed = True
@ -802,6 +801,7 @@ class AzureRMVirtualMachine(AzureRMModuleBase):
if changed: if changed:
if self.state == 'present': if self.state == 'present':
default_storage_account = None
if not vm: if not vm:
# Create the VM # Create the VM
self.log("Create virtual machine {0}".format(self.name)) self.log("Create virtual machine {0}".format(self.name))
@ -835,6 +835,7 @@ class AzureRMVirtualMachine(AzureRMModuleBase):
self._cloud_environment.suffixes.storage_endpoint, self._cloud_environment.suffixes.storage_endpoint,
self.storage_container_name, self.storage_container_name,
self.storage_blob_name) self.storage_blob_name)
default_storage_account = storage_account # store for use by data disks if necessary
if not self.short_hostname: if not self.short_hostname:
self.short_hostname = self.name self.short_hostname = self.name
@ -904,18 +905,22 @@ class AzureRMVirtualMachine(AzureRMModuleBase):
count += 1 count += 1
if data_disk.get('storage_account_name'): if data_disk.get('storage_account_name'):
self.get_storage_account(data_disk['storage_account_name']) data_disk_storage_account = self.get_storage_account(data_disk['storage_account_name'])
data_disk_storage_account.name = data_disk['storage_account_name']
else: else:
if(not default_storage_account):
data_disk_storage_account = self.create_default_storage_account() data_disk_storage_account = self.create_default_storage_account()
self.log("data disk storage account:") self.log("data disk storage account:")
self.log(self.serialize_obj(data_disk_storage_account, 'StorageAccount'), pretty_print=True) self.log(self.serialize_obj(data_disk_storage_account, 'StorageAccount'), pretty_print=True)
default_storage_account = data_disk_storage_account # store for use by future data disks if necessary
else:
data_disk_storage_account = default_storage_account
if not data_disk.get('storage_container_name'): if not data_disk.get('storage_container_name'):
data_disk['storage_container_name'] = 'vhds' data_disk['storage_container_name'] = 'vhds'
data_disk_requested_vhd_uri = 'https://{0}.blob.core.windows.net/{1}/{2}'.format( data_disk_requested_vhd_uri = 'https://{0}.blob.{1}/{2}/{3}'.format(
data_disk_storage_account.name, data_disk_storage_account.name,
self._cloud_environment.suffixes.storage_endpoint,
data_disk['storage_container_name'], data_disk['storage_container_name'],
data_disk['storage_blob_name'] data_disk['storage_blob_name']
) )
@ -1182,20 +1187,31 @@ class AzureRMVirtualMachine(AzureRMModuleBase):
def delete_vm(self, vm): def delete_vm(self, vm):
vhd_uris = [] vhd_uris = []
managed_disk_ids = []
nic_names = [] nic_names = []
pip_names = [] pip_names = []
if self.remove_on_absent.intersection(set(['all','virtual_storage'])): if self.remove_on_absent.intersection(set(['all','virtual_storage'])):
# store the attached vhd info so we can nuke it after the VM is gone # store the attached vhd info so we can nuke it after the VM is gone
if(vm.storage_profile.os_disk.managed_disk):
self.log('Storing managed disk ID for deletion')
managed_disk_ids.append(vm.storage_profile.os_disk.managed_disk.id)
elif(vm.storage_profile.os_disk.vhd):
self.log('Storing VHD URI for deletion') self.log('Storing VHD URI for deletion')
vhd_uris.append(vm.storage_profile.os_disk.vhd.uri) vhd_uris.append(vm.storage_profile.os_disk.vhd.uri)
data_disks = vm.storage_profile.data_disks data_disks = vm.storage_profile.data_disks
for data_disk in data_disks: for data_disk in data_disks:
if(data_disk.vhd):
vhd_uris.append(data_disk.vhd.uri) vhd_uris.append(data_disk.vhd.uri)
elif(data_disk.managed_disk):
managed_disk_ids.append(data_disk.managed_disk.id)
# FUTURE enable diff mode, move these there...
self.log("VHD URIs to delete: {0}".format(', '.join(vhd_uris))) self.log("VHD URIs to delete: {0}".format(', '.join(vhd_uris)))
self.results['deleted_vhd_uris'] = vhd_uris self.results['deleted_vhd_uris'] = vhd_uris
self.log("Managed disk IDs to delete: {0}".format(', '.join(managed_disk_ids)))
self.results['deleted_managed_disk_ids'] = managed_disk_ids
if self.remove_on_absent.intersection(set(['all','network_interfaces'])): if self.remove_on_absent.intersection(set(['all','network_interfaces'])):
# store the attached nic info so we can nuke them after the VM is gone # store the attached nic info so we can nuke them after the VM is gone
@ -1228,8 +1244,10 @@ class AzureRMVirtualMachine(AzureRMModuleBase):
# TODO: parallelize nic, vhd, and public ip deletions with begin_deleting # TODO: parallelize nic, vhd, and public ip deletions with begin_deleting
# TODO: best-effort to keep deleting other linked resources if we encounter an error # TODO: best-effort to keep deleting other linked resources if we encounter an error
if self.remove_on_absent.intersection(set(['all','virtual_storage'])): if self.remove_on_absent.intersection(set(['all','virtual_storage'])):
self.log('Deleting virtual storage') self.log('Deleting VHDs')
self.delete_vm_storage(vhd_uris) self.delete_vm_storage(vhd_uris)
self.log('Deleting managed disks')
self.delete_managed_disks(managed_disk_ids)
if self.remove_on_absent.intersection(set(['all','network_interfaces'])): if self.remove_on_absent.intersection(set(['all','network_interfaces'])):
self.log('Deleting network interfaces') self.log('Deleting network interfaces')
@ -1270,7 +1288,16 @@ class AzureRMVirtualMachine(AzureRMModuleBase):
# Delete returns nada. If we get here, assume that all is well. # Delete returns nada. If we get here, assume that all is well.
return True return True
def delete_managed_disks(self, managed_disk_ids):
for mdi in managed_disk_ids:
try:
poller = self.rm_client.resources.delete_by_id(mdi, '2017-03-30')
self.get_poller_result(poller)
except Exception as exc:
self.fail("Error deleting managed disk {0} - {1}".format(mdi, str(exc)))
def delete_vm_storage(self, vhd_uris): def delete_vm_storage(self, vhd_uris):
# FUTURE: figure out a cloud_env indepdendent way to delete these
for uri in vhd_uris: for uri in vhd_uris:
self.log("Extracting info from blob uri '{0}'".format(uri)) self.log("Extracting info from blob uri '{0}'".format(uri))
try: try:
@ -1354,7 +1381,7 @@ class AzureRMVirtualMachine(AzureRMModuleBase):
valid_name = False valid_name = False
# Attempt to find a valid storage account name # Attempt to find a valid storage account name
storage_account_name_base = self.name[:20].lower() storage_account_name_base = re.sub('[^a-zA-Z0-9]', '', self.name[:20].lower())
for i in range(0, 5): for i in range(0, 5):
rand = random.randrange(1000, 9999) rand = random.randrange(1000, 9999)
storage_account_name = storage_account_name_base + str(rand) storage_account_name = storage_account_name_base + str(rand)
@ -1392,8 +1419,11 @@ class AzureRMVirtualMachine(AzureRMModuleBase):
self.log("Checking storage account name availability for {0}".format(name)) self.log("Checking storage account name availability for {0}".format(name))
try: try:
response = self.storage_client.storage_accounts.check_name_availability(name) response = self.storage_client.storage_accounts.check_name_availability(name)
if response.reason == 'AccountNameInvalid':
raise Exception("Invalid default storage account name: {0}".format(name))
except Exception as exc: except Exception as exc:
self.fail("Error checking storage account name availability for {0} - {1}".format(name, str(exc))) self.fail("Error checking storage account name availability for {0} - {1}".format(name, str(exc)))
return response.name_available return response.name_available
def create_default_nic(self): def create_default_nic(self):

Loading…
Cancel
Save