New module request: azure_rm_virtualmachine_facts #38081 (#38279)

* New module request: azure_rm_virtualmachine_facts #38081

* New module request: azure_rm_virtualmachine_facts #38081 #38279 pep8 fixes

* New module request: azure_rm_virtualmachine_facts #38081 #38279 validate-modules fixes

* New module request: azure_rm_virtualmachine_facts #38081 #38279 serialize_vm

* New module request: azure_rm_virtualmachine_facts #38081 #38279 get_item

* New module request: azure_rm_virtualmachine_facts #38081 #38279 avoid get vm twice

* New module request: azure_rm_virtualmachine_facts #38081 #38279 some jborean93 requests

* New module request: azure_rm_virtualmachine_facts #38081 #38279 camel_dict_to_snake_dict

* New module request: azure_rm_virtualmachine_facts #38081 #38279 integration test

* New module request: azure_rm_virtualmachine_facts #38081 #38279 virtual network required

* New module request: azure_rm_virtualmachine_facts #38081 #38279 consider additional vms present

* New module request: azure_rm_virtualmachine_facts #38081 #38279 trailing comma

* New module request: azure_rm_virtualmachine_facts #38081 #38279 remove from smoketest

* New module request: azure_rm_virtualmachine_facts #38081 #38279 filtering by tag fix

* New module request: azure_rm_virtualmachine_facts #38081 #38279 virtual network issues fix

* New module request: azure_rm_virtualmachine_facts #38081 #38279 remove trailing comma

* adding curated format for vm

* New module request: azure_rm_virtualmachine_facts #38081 #38279 rights to zim + lint fixes

* clean up

* updates to vm facts

* commented out failing thing

* fixed mistake

* New module request: azure_rm_virtualmachine_facts #38081

* New module request: azure_rm_virtualmachine_facts #38081 #38279 pep8 fixes

* New module request: azure_rm_virtualmachine_facts #38081 #38279 validate-modules fixes

* fixed test

* fixed test problem

* New module request: azure_rm_virtualmachine_facts #38081 #38279 serialize_vm

* New module request: azure_rm_virtualmachine_facts #38081 #38279 get_item

* New module request: azure_rm_virtualmachine_facts #38081 #38279 avoid get vm twice

* New module request: azure_rm_virtualmachine_facts #38081 #38279 some jborean93 requests

* New module request: azure_rm_virtualmachine_facts #38081 #38279 camel_dict_to_snake_dict

* New module request: azure_rm_virtualmachine_facts #38081 #38279 integration test

* New module request: azure_rm_virtualmachine_facts #38081 #38279 virtual network required

* New module request: azure_rm_virtualmachine_facts #38081 #38279 consider additional vms present

* New module request: azure_rm_virtualmachine_facts #38081 #38279 trailing comma

* New module request: azure_rm_virtualmachine_facts #38081 #38279 remove from smoketest

* New module request: azure_rm_virtualmachine_facts #38081 #38279 filtering by tag fix

* New module request: azure_rm_virtualmachine_facts #38081 #38279 virtual network issues fix

* New module request: azure_rm_virtualmachine_facts #38081 #38279 remove trailing comma

* adding curated format for vm

* New module request: azure_rm_virtualmachine_facts #38081 #38279 rights to zim + lint fixes

* clean up

* updates to vm facts

* commented out failing thing

* fixed mistake

* fixed test

* fixed test problem

* ldap_entry 'Tuple_to_LDAPMod(): expected a byte string in the list' issue

* Revert "ldap_entry 'Tuple_to_LDAPMod(): expected a byte string in the list' issue"

This reverts commit efe316c52e5a70fc1aa9f58eff3a9d5b2599763f.

* changed return value

* fixed test

* fixed test mistake

* one space too much

* removed change made by mistake

* virtual machine description

* remove example

* fixed yaml
This commit is contained in:
Gustavo Muniz do Carmo 2018-08-01 03:23:50 +01:00 committed by Zim Kalinowski
parent f24054121a
commit 5149ab1e00
2 changed files with 379 additions and 21 deletions

View file

@ -0,0 +1,340 @@
#!/usr/bin/python
#
# Copyright (c) 2018
# Gustavo Muniz do Carmo <gustavo@esign.com.br>
# Zim Kalinowski <zikalino@microsoft.com>
#
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = '''
---
module: azure_rm_virtualmachine_facts
version_added: "2.7"
short_description: Get virtual machine facts.
description:
- Get facts for all virtual machines of a resource group.
options:
resource_group:
description:
- Name of the resource group containing the virtual machines (required when filtering by vm name).
name:
description:
- Name of the virtual machine.
tags:
description:
- Limit results by providing a list of tags. Format tags as 'key' or 'key:value'.
extends_documentation_fragment:
- azure
author:
- "Gustavo Muniz do Carmo (@gustavomcarmo)"
- "Zim Kalinowski (@zikalino)"
'''
EXAMPLES = '''
- name: Get facts for all virtual machines of a resource group
azure_rm_virtualmachine_facts:
resource_group: Testing
- name: Get facts by name
azure_rm_virtualmachine_facts:
resource_group: Testing
name: vm
- name: Get facts by tags
azure_rm_virtualmachine_facts:
resource_group: Testing
tags:
- testing
- foo:bar
'''
RETURN = '''
vms:
description: List of virtual machines.
returned: always
type: complex
contains:
admin_username:
description:
- Administrator user name.
returned: always
type: str
sample: admin
data_disks:
description:
- List of attached data disks.
returned: always
type: complex
contains:
caching:
description:
- Type of data disk caching.
type: str
sample: ReadOnly
disk_size_gb:
description:
- The initial disk size in GB for blank data disks
type: int
sample: 64
lun:
description:
- The logical unit number for data disk
type: int
sample: 0
managed_disk_type:
description:
- Managed data disk type
type: str
sample: Standard_LRS
id:
description:
- Resource ID.
returned: always
type: str
sample: /subscriptions/075da289-5dfd-466b-800e-a8c3a9ed3b05/resourceGroups/myclusterrg/providers/Microsoft.Compute/virtualMachines/mycluster-node-2
image:
description:
- Image specification
returned: always
type: complex
contains:
offer:
description:
- Offer.
type: str
sample: RHEL
publisher:
description:
- Publisher name.
type: str
sample: RedHat
sku:
description:
- SKU name.
type: str
sample: 7-RAW
version:
description:
- Image version.
type: str
sample: 7.5.2018050901
location:
description:
- Resource location.
returned: always
type: str
sample: japaneast
name:
description:
- Resource name.
returned: always
type: str
sample: mycluster-node-2
network_interface_names:
description:
- List of attached network interfaces.
type: list
sample: [
"mycluster-node-2-nic"
]
os_disk_caching:
description:
- Type of OS disk caching.
type: str
sample: ReadOnly
os_type:
description:
- Base type of operating system.
type: str
sample: Linux
resource_group:
description:
- Resource group.
type: str
state:
description:
- State of the resource.
type: str
sample: present
tags:
description:
- Tags.
type: dict
vm_size:
description:
- Virtual machine size.
type: str
sample: Standard_D4
'''
try:
from msrestazure.azure_exceptions import CloudError
except:
# This is handled in azure_rm_common
pass
from ansible.module_utils.azure_rm_common import AzureRMModuleBase, azure_id_to_dict
from ansible.module_utils.common.dict_transformations import camel_dict_to_snake_dict
from ansible.module_utils.six.moves.urllib.parse import urlparse
import re
AZURE_OBJECT_CLASS = 'VirtualMachine'
AZURE_ENUM_MODULES = ['azure.mgmt.compute.models']
class AzureRMVirtualMachineFacts(AzureRMModuleBase):
def __init__(self):
self.module_arg_spec = dict(
resource_group=dict(type='str'),
name=dict(type='str'),
tags=dict(type='list')
)
self.results = dict(
changed=False,
vms=[]
)
self.resource_group = None
self.name = None
self.tags = None
super(AzureRMVirtualMachineFacts, self).__init__(self.module_arg_spec,
supports_tags=False,
facts_module=True)
def exec_module(self, **kwargs):
for key in self.module_arg_spec:
setattr(self, key, kwargs[key])
if self.name and not self.resource_group:
self.fail("Parameter error: resource group required when filtering by name.")
if self.name:
self.results['vms'] = self.get_item()
else:
self.results['vms'] = self.list_items()
return self.results
def get_item(self):
self.log('Get properties for {0}'.format(self.name))
item = None
result = []
try:
item = self.compute_client.virtual_machines.get(self.resource_group, self.name)
except CloudError as err:
self.module.warn("Error getting virtual machine {0} - {1}".format(self.name, str(err)))
if item and self.has_tags(item.tags, self.tags):
result = [self.serialize_vm(item)]
return result
def list_items(self):
self.log('List all items')
try:
items = self.compute_client.virtual_machines.list(self.resource_group)
except CloudError as exc:
self.fail("Failed to list all items - {0}".format(str(exc)))
results = []
for item in items:
if self.has_tags(item.tags, self.tags):
results.append(self.serialize_vm(self.get_vm(item.name)))
return results
def get_vm(self, name):
'''
Get the VM with expanded instanceView
:return: VirtualMachine object
'''
try:
vm = self.compute_client.virtual_machines.get(self.resource_group, name, expand='instanceview')
return vm
except Exception as exc:
self.fail("Error getting virtual machine {0} - {1}".format(self.name, str(exc)))
def serialize_vm(self, vm):
'''
Convert a VirtualMachine object to dict.
:param vm: VirtualMachine object
:return: dict
'''
result = self.serialize_obj(vm, AZURE_OBJECT_CLASS, enum_modules=AZURE_ENUM_MODULES)
new_result = {}
new_result['id'] = vm.id
new_result['resource_group'] = re.sub('\\/.*', '', re.sub('.*resourceGroups\\/', '', result['id']))
new_result['name'] = vm.name
new_result['state'] = 'present'
new_result['location'] = vm.location
new_result['vm_size'] = result['properties']['hardwareProfile']['vmSize']
new_result['admin_username'] = result['properties']['osProfile']['adminUsername']
image = result['properties']['storageProfile'].get('imageReference')
if image is not None:
new_result['image'] = {
'publisher': image['publisher'],
'sku': image['sku'],
'offer': image['offer'],
'version': image['version']
}
vhd = result['properties']['storageProfile']['osDisk'].get('vhd')
if vhd is not None:
url = urlparse(vhd['uri'])
new_result['storage_account_name'] = url.netloc.split('.')[0]
new_result['storage_container_name'] = url.path.split('/')[1]
new_result['storage_blob_name'] = url.path.split('/')[-1]
new_result['os_disk_caching'] = result['properties']['storageProfile']['osDisk']['caching']
new_result['os_type'] = result['properties']['storageProfile']['osDisk']['osType']
new_result['data_disks'] = []
disks = result['properties']['storageProfile']['dataDisks']
for disk_index in range(len(disks)):
new_result['data_disks'].append({
'lun': disks[disk_index]['lun'],
'disk_size_gb': disks[disk_index]['diskSizeGB'],
'managed_disk_type': disks[disk_index]['managedDisk']['storageAccountType'],
'caching': disks[disk_index]['caching']
})
new_result['network_interface_names'] = []
nics = result['properties']['networkProfile']['networkInterfaces']
for nic_index in range(len(nics)):
new_result['network_interface_names'].append(re.sub('.*networkInterfaces/', '', nics[nic_index]['id']))
new_result['tags'] = vm.tags
return new_result
def main():
AzureRMVirtualMachineFacts()
if __name__ == '__main__':
main()

View file

@ -116,29 +116,29 @@
timeout: 60 timeout: 60
state: started state: started
- block: #- block:
# TODO: figure out how to make this work under ansible-test with the coverage injector # TODO: figure out how to make this work under ansible-test with the coverage injector
#- name: wait for host to answer on SSH # - name: wait for host to answer on SSH
# delegate_to: new_azure_vm # delegate_to: new_azure_vm
# wait_for_connection: # wait_for_connection:
- name: get content from custom_data script # - name: get content from custom_data script
raw: cat /tmp/custom_data.txt # raw: cat /tmp/custom_data.txt
register: custom_data_content # register: custom_data_content
- name: assert contents # - name: assert contents
assert: # assert:
that: custom_data_content.stdout | regex_search('custom_data was executed') # that: custom_data_content.stdout | regex_search('custom_data was executed')
delegate_to: new_azure_vm # delegate_to: new_azure_vm
# TODO: figure out how to make this work under ansible-test with the coverage injector # TODO: figure out how to make this work under ansible-test with the coverage injector
#- name: wait for file/content created by custom_data script # - name: wait for file/content created by custom_data script
# delegate_to: new_azure_vm # delegate_to: new_azure_vm
# vars: # vars:
# ansible_python_interpreter: python # ansible_python_interpreter: python
# wait_for: # wait_for:
# path: /tmp/custom_data.txt # path: /tmp/custom_data.txt
# search_regex: ^custom_data was executed$ # search_regex: ^custom_data was executed$
# timeout: 20 # timeout: 20
- name: Restart the virtual machine - name: Restart the virtual machine
azure_rm_virtualmachine: azure_rm_virtualmachine:
@ -296,6 +296,24 @@
that: that:
- azure_vm.properties.availabilitySet.id - azure_vm.properties.availabilitySet.id
- name: Retrieve vms facts (filtering by name)
azure_rm_virtualmachine_facts:
resource_group: "{{ resource_group }}"
name: testvm003
register: results
- name: Just dump output
debug:
var: results
- name: Assert that facts module returned the second vm
assert:
that:
- results.vms | length == 1
- results.vms[0].name == 'testvm003'
- results.vms[0].location == 'eastus'
- results.vms[0].admin_username == 'adminuser'
- name: Should be idempotent with a dual NICs - name: Should be idempotent with a dual NICs
vars: vars:
niclist: niclist: