add custom_action support to azure_rm_virtualmachine (#34970)

* Adds custom_data parameter to azure virtual machine resource

Invoke custom_data in an integration test: This invocation of
custom_data should not cause any side effects.

* Bugfix: String encoding now works in both python2 and 3

* Fix pep8 violations

* Use nginx to serve a text file created via custom_data and verify that
that custom_data is working

* fix up azure_rm_virtualmachine custom_data

* tweaks #25924 
* simplify string encoding fun
* don't rely on external packages
This commit is contained in:
Matt Davis 2018-01-16 21:05:35 -08:00 committed by GitHub
parent e9b52aca64
commit d7fbc94758
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 78 additions and 2 deletions

View file

@ -38,6 +38,12 @@ options:
description:
- Name of the virtual machine.
required: true
custom_data:
description:
- Data which is made available to the virtual machine and used by e.g., cloud-init.
default: null
required: false
version_added: "2.5"
state:
description:
- Assert the state of the virtual machine.
@ -591,6 +597,7 @@ azure_vm:
}
''' # NOQA
import base64
import random
import re
@ -601,6 +608,7 @@ except ImportError:
# This is handled in azure_rm_common
pass
from ansible.module_utils.basic import to_native, to_bytes
from ansible.module_utils.azure_rm_common import AzureRMModuleBase, azure_id_to_dict
@ -626,6 +634,7 @@ class AzureRMVirtualMachine(AzureRMModuleBase):
self.module_arg_spec = dict(
resource_group=dict(type='str', required=True),
name=dict(type='str', required=True),
custom_data=dict(type='str'),
state=dict(choices=['present', 'absent'], default='present', type='str'),
location=dict(type='str'),
short_hostname=dict(type='str'),
@ -660,6 +669,7 @@ class AzureRMVirtualMachine(AzureRMModuleBase):
self.resource_group = None
self.name = None
self.custom_data = None
self.state = None
self.location = None
self.short_hostname = None
@ -970,6 +980,10 @@ class AzureRMVirtualMachine(AzureRMModuleBase):
if self.admin_password:
vm_resource.os_profile.admin_password = self.admin_password
if self.custom_data:
# Azure SDK (erroneously?) wants native string type for this
vm_resource.os_profile.custom_data = to_native(base64.b64encode(to_bytes(self.custom_data)))
if self.os_type == 'Linux':
vm_resource.os_profile.linux_configuration = self.compute_models.LinuxConfiguration(
disable_password_authentication=disable_ssh_password
@ -1101,6 +1115,12 @@ class AzureRMVirtualMachine(AzureRMModuleBase):
if vm_dict.get('tags'):
vm_resource.tags = vm_dict['tags']
# Add custom_data, if provided
if vm_dict['properties']['osProfile'].get('customData'):
custom_data = vm_dict['properties']['osProfile']['customData']
# Azure SDK (erroneously?) wants native string type for this
vm_resource.os_profile.custom_data = to_native(base64.b64encode(to_bytes(custom_data)))
# Add admin password, if one provided
if vm_dict['properties']['osProfile'].get('adminPassword'):
vm_resource.os_profile.admin_password = vm_dict['properties']['osProfile']['adminPassword']
@ -1667,5 +1687,6 @@ class AzureRMVirtualMachine(AzureRMModuleBase):
def main():
AzureRMVirtualMachine()
if __name__ == '__main__':
main()

View file

@ -44,6 +44,20 @@
azure_rm_securitygroup:
resource_group: "{{ resource_group }}"
name: testvm001
purge_rules: yes
rules:
- name: ALLOW_SSH
protocol: Tcp
destination_port_range: 22
access: Allow
priority: 100
direction: Inbound
- name: ALLOW_HTTP
protocol: Tcp
destination_port_range: 80
access: Allow
priority: 110
direction: Inbound
- name: Create NIC
azure_rm_networkinterface:
@ -55,6 +69,7 @@
security_group: testvm001
- name: Create virtual machine
register: output
azure_rm_virtualmachine:
resource_group: "{{ resource_group }}"
name: testvm002
@ -73,12 +88,52 @@
publisher: Canonical
sku: 16.04-LTS
version: latest
register: output
custom_data: |
#!/bin/sh
echo "custom_data was executed" > /tmp/custom_data.txt
- assert:
that:
- azure_vm.properties.availabilitySet.id
- add_host:
name: new_azure_vm
ansible_host: '{{ output.ansible_facts.azure_vm.properties.networkProfile.networkInterfaces[0].properties.ipConfigurations[0].properties.publicIPAddress.properties.ipAddress }}'
ansible_connection: paramiko # not guaranteed to have sshpass...
ansible_user: adminuser
ansible_password: Password123!
- name: wait for SSH port to be open
wait_for:
host: '{{ hostvars["new_azure_vm"].ansible_host }}'
port: 22
timeout: 60
state: started
- block:
# TODO: figure out how to make this work under ansible-test with the coverage injector
#- name: wait for host to answer on SSH
# delegate_to: new_azure_vm
# wait_for_connection:
- name: get content from custom_data script
raw: cat /tmp/custom_data.txt
register: custom_data_content
- name: assert contents
assert:
that: custom_data_content.stdout | regex_search('custom_data was executed')
delegate_to: new_azure_vm
# 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
# delegate_to: new_azure_vm
# vars:
# ansible_python_interpreter: python
# wait_for:
# path: /tmp/custom_data.txt
# search_regex: ^custom_data was executed$
# timeout: 20
- name: Restart the virtual machine
azure_rm_virtualmachine:
resource_group: "{{ resource_group }}"
@ -205,4 +260,4 @@
image:
name: invalid-image
register: fail_missing_custom_image_dict
failed_when: fail_missing_custom_image_dict.msg != "Error could not find image with name invalid-image"
failed_when: fail_missing_custom_image_dict.msg != "Error could not find image with name invalid-image"