From f8aaa7dcd22f39594175c696edaa3322ef93ec6f Mon Sep 17 00:00:00 2001 From: Abhijeet Kasurde Date: Tue, 3 Mar 2020 06:49:16 +0530 Subject: [PATCH] [2.9] VMware: vmware_export_ovf module fix Python3 compatibility issue (#67514) (cherry picked from commit 023a9b31661febdff3fb7650b27ba65278971549) Co-authored-by: Diane Wang <41371902+Tomorrow9@users.noreply.github.com> --- .../60265-vmware_export_ovf-py3fix.yml | 2 + .../modules/cloud/vmware/vmware_export_ovf.py | 11 +-- .../targets/vmware_export_ovf/aliases | 3 + .../targets/vmware_export_ovf/tasks/main.yml | 69 +++++++++++++++++++ 4 files changed, 80 insertions(+), 5 deletions(-) create mode 100644 changelogs/fragments/60265-vmware_export_ovf-py3fix.yml create mode 100644 test/integration/targets/vmware_export_ovf/aliases create mode 100644 test/integration/targets/vmware_export_ovf/tasks/main.yml diff --git a/changelogs/fragments/60265-vmware_export_ovf-py3fix.yml b/changelogs/fragments/60265-vmware_export_ovf-py3fix.yml new file mode 100644 index 00000000000..8306cd19be7 --- /dev/null +++ b/changelogs/fragments/60265-vmware_export_ovf-py3fix.yml @@ -0,0 +1,2 @@ +bugfixes: +- Fix Python3 compatibility for vmware_export_ovf module. diff --git a/lib/ansible/modules/cloud/vmware/vmware_export_ovf.py b/lib/ansible/modules/cloud/vmware/vmware_export_ovf.py index e04cd969f3a..338a5ee0214 100644 --- a/lib/ansible/modules/cloud/vmware/vmware_export_ovf.py +++ b/lib/ansible/modules/cloud/vmware/vmware_export_ovf.py @@ -112,7 +112,7 @@ from time import sleep from threading import Thread from ansible.module_utils.urls import open_url from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils._text import to_text +from ansible.module_utils._text import to_text, to_bytes from ansible.module_utils.vmware import vmware_argument_spec, PyVmomi try: from pyVmomi import vim @@ -179,6 +179,7 @@ class VMwareExportVmOvf(PyVmomi): total_bytes_to_write): mf_content = 'SHA256(' + os.path.basename(temp_target_disk) + ')= ' sha256_hash = hashlib.sha256() + response = None with open(self.mf_file, 'a') as mf_handle: with open(temp_target_disk, 'wb') as handle: @@ -300,9 +301,9 @@ class VMwareExportVmOvf(PyVmomi): ovf_descriptor_path = os.path.join(self.ovf_dir, ovf_descriptor_name + '.ovf') sha256_hash = hashlib.sha256() with open(self.mf_file, 'a') as mf_handle: - with open(ovf_descriptor_path, 'wb') as handle: + with open(ovf_descriptor_path, 'w') as handle: handle.write(vm_descriptor) - sha256_hash.update(vm_descriptor) + sha256_hash.update(to_bytes(vm_descriptor)) mf_handle.write('SHA256(' + os.path.basename(ovf_descriptor_path) + ')= ' + sha256_hash.hexdigest() + '\n') http_nfc_lease.HttpNfcLeaseProgress(100) # self.facts = http_nfc_lease.HttpNfcLeaseGetManifest() @@ -313,7 +314,7 @@ class VMwareExportVmOvf(PyVmomi): kwargs = { 'changed': False, 'failed': True, - 'msg': to_text(err), + 'msg': "get exception: %s" % to_text(err), } http_nfc_lease.HttpNfcLeaseAbort() lease_updater.stop() @@ -348,9 +349,9 @@ def main(): if vm_power_state != 'poweredoff': module.fail_json(msg='VM state should be poweredoff to export') results = pyv.export_to_ovf_files(vm_obj=vm) + module.exit_json(**results) else: module.fail_json(msg='The specified virtual machine not found') - module.exit_json(**results) if __name__ == '__main__': diff --git a/test/integration/targets/vmware_export_ovf/aliases b/test/integration/targets/vmware_export_ovf/aliases new file mode 100644 index 00000000000..3eede2cbf01 --- /dev/null +++ b/test/integration/targets/vmware_export_ovf/aliases @@ -0,0 +1,3 @@ +cloud/vcenter +shippable/vcenter/group1 +needs/target/prepare_vmware_tests diff --git a/test/integration/targets/vmware_export_ovf/tasks/main.yml b/test/integration/targets/vmware_export_ovf/tasks/main.yml new file mode 100644 index 00000000000..5bada2f74bb --- /dev/null +++ b/test/integration/targets/vmware_export_ovf/tasks/main.yml @@ -0,0 +1,69 @@ +# Test code for the vmware_export_ovf module +# Copyright: (c) 2019, Diane Wang (Tomorrow9) +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +- when: vcsim is not defined + block: + - name: create temporary build directory + tempfile: + state: directory + suffix: build + register: temp_dir + - debug: var=temp_dir + + - import_role: + name: prepare_vmware_tests + vars: + setup_attach_host: true + setup_datastore: true + setup_virtualmachines: true + + - name: set state to poweroff on the tested VM + vmware_guest: + validate_certs: False + hostname: "{{ vcenter_hostname }}" + username: "{{ vcenter_username }}" + password: "{{ vcenter_password }}" + name: "{{ virtual_machines_in_cluster[0].name }}" + state: poweredoff + + - name: export VM to ovf template + vmware_export_ovf: + validate_certs: False + hostname: "{{ vcenter_hostname }}" + username: "{{ vcenter_username }}" + password: "{{ vcenter_password }}" + name: "{{ virtual_machines_in_cluster[0].name }}" + datacenter: "{{ dc1 }}" + export_dir: "{{ temp_dir.path }}" + register: ovf_template + - debug: var=ovf_template + - name: assert the ovf template exported + assert: + that: + - "ovf_template.changed == true" + - "ovf_template.instance.device_files | length >= 1" + + - name: export VM to ovf template with timeout set + vmware_export_ovf: + validate_certs: False + hostname: "{{ vcenter_hostname }}" + username: "{{ vcenter_username }}" + password: "{{ vcenter_password }}" + name: "{{ virtual_machines_in_cluster[0].name }}" + datacenter: "{{ dc1 }}" + export_dir: "{{ temp_dir.path }}" + download_timeout: 30 + register: ovf_template + - debug: var=ovf_template + - name: assert the ovf template exported + assert: + that: + - "ovf_template.changed == true" + - "ovf_template.instance.device_files | length >= 1" + rescue: + - name: Clean up the temporary dir + file: + path: "{{ temp_dir.path }}" + state: absent + when: temp_dir.path is defined