diff --git a/lib/ansible/modules/cloud/vmware/vmware_cfg_backup.py b/lib/ansible/modules/cloud/vmware/vmware_cfg_backup.py index 460b4988e9..1e3f30129e 100644 --- a/lib/ansible/modules/cloud/vmware/vmware_cfg_backup.py +++ b/lib/ansible/modules/cloud/vmware/vmware_cfg_backup.py @@ -5,14 +5,6 @@ # Author(s): Andreas Nafpliotis # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) -# Ansible is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with Ansible. If not, see = 2.6" - PyVmomi installed options: + esxi_hostname: + description: + - Name of ESXi server. + required: False dest: description: - The destination where the ESXi configuration bundle will be saved. The I(dest) can be a folder or a file. @@ -44,18 +40,18 @@ options: - If I(dest) is a file, the backup file will be saved with that filename. The file extension will always be .tgz. src: description: - - The file containing the ESXi configuration that will be restored + - The file containing the ESXi configuration that will be restored. state: description: - If C(saved), the .tgz backup bundle will be saved in I(dest). - - If C(absent), the host configuration will be resetted to default values. + - If C(absent), the host configuration will be reset to default values. - If C(loaded), the backup file in I(src) will be loaded to the ESXi host rewriting the hosts settings. choices: [saved, absent, loaded] extends_documentation_fragment: vmware.documentation ''' EXAMPLES = ''' -#save the ESXi configuration locally +# save the ESXi configuration locally - name: ESXI backup test local_action: module: vmware_cfg_backup @@ -64,6 +60,17 @@ EXAMPLES = ''' password: pass state: saved dest: /tmp/ + +# save the ESXi configuration locally for specific ESXi +- name: ESXI backup test + local_action: + module: vmware_cfg_backup + hostname: vCenter + esxi_hostname: esxi_hostname + username: user + password: pass + state: saved + dest: /tmp/ ''' RETURN = ''' @@ -75,22 +82,21 @@ dest_file: ''' import os - try: from pyVmomi import vim, vmodl - HAS_PYVMOMI = True except ImportError: - HAS_PYVMOMI = False + pass -from ansible.module_utils.vmware import vmware_argument_spec, connect_to_api, get_all_objs, wait_for_task +from ansible.module_utils.vmware import vmware_argument_spec, get_all_objs, wait_for_task, PyVmomi from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.urls import open_url from ansible.module_utils.six.moves.urllib.error import HTTPError +from ansible.module_utils._text import to_native -class VMwareConfigurationBackup(object): +class VMwareConfigurationBackup(PyVmomi): def __init__(self, module): - self.module = module + super(VMwareConfigurationBackup, self).__init__(module) self.state = self.module.params['state'] self.dest = self.module.params['dest'] self.src = self.module.params['src'] @@ -98,10 +104,17 @@ class VMwareConfigurationBackup(object): self.username = self.module.params['username'] self.password = self.module.params['password'] self.validate_certs = self.module.params['validate_certs'] - self.content = connect_to_api(self.module) + self.esxi_hostname = self.module.params.get('esxi_hostname', None) self.host = self.find_host_system() def find_host_system(self): + if self.esxi_hostname: + host_system_obj = self.find_hostsystem_by_name(host_name=self.esxi_hostname) + if host_system_obj: + return host_system_obj + else: + self.module.fail_json(msg="Failed to find ESXi %s" % self.esxi_hostname) + host_system = get_all_objs(self.content, [vim.HostSystem]) return host_system.keys()[0] @@ -133,7 +146,7 @@ class VMwareConfigurationBackup(object): request = open_url(url=url, data=data, method='PUT', validate_certs=self.validate_certs, url_username=self.username, url_password=self.password, force_basic_auth=True) except Exception as e: - self.module.fail_json(msg=str(e)) + self.module.fail_json(msg=to_native(e)) if not self.host.runtime.inMaintenanceMode: self.enter_maintenance() @@ -142,7 +155,7 @@ class VMwareConfigurationBackup(object): self.module.exit_json(changed=True) except Exception as e: self.exit_maintenance() - self.module.fail_json(msg=str(e)) + self.module.fail_json(msg=to_native(e)) def reset_configuration(self): if not self.host.runtime.inMaintenanceMode: @@ -152,7 +165,7 @@ class VMwareConfigurationBackup(object): self.module.exit_json(changed=True) except Exception as e: self.exit_maintenance() - self.module.fail_json(msg=str(e)) + self.module.fail_json(msg=to_native(e)) def save_configuration(self): url = self.host.configManager.firmwareSystem.BackupFirmwareConfiguration() @@ -170,38 +183,39 @@ class VMwareConfigurationBackup(object): file.write(request.read()) self.module.exit_json(changed=True, dest_file=self.dest) except IOError as e: - self.module.fail_json(msg="Failed to write backup file. Ensure that the dest path exists and is writable.") + self.module.fail_json(msg="Failed to write backup file. Ensure that " + "the dest path exists and is writable. Details : %s" % to_native(e)) except Exception as e: - self.module.fail_json(msg=str(e)) + self.module.fail_json(msg=to_native(e)) def enter_maintenance(self): try: task = self.host.EnterMaintenanceMode_Task(timeout=15) success, result = wait_for_task(task) except Exception as e: - self.module.fail_json(msg="Failed to enter maintenance mode. Ensure that there are no powered on machines on the host.") + self.module.fail_json(msg="Failed to enter maintenance mode." + " Ensure that there are no powered on machines on the host. %s" % to_native(e)) def exit_maintenance(self): try: task = self.host.ExitMaintenanceMode_Task(timeout=15) success, result = wait_for_task(task) - except Exception as e: - self.module.fail_json(msg="Failed to exit maintenance mode") + except Exception as generic_exc: + self.module.fail_json(msg="Failed to exit maintenance mode due to %s" % to_native(generic_exc)) def main(): - argument_spec = vmware_argument_spec() argument_spec.update(dict(dest=dict(required=False, type='path'), + esxi_hostname=dict(required=False, type='str'), src=dict(required=False, type='path'), state=dict(required=True, choices=['saved', 'absent', 'loaded'], type='str'))) required_if = [('state', 'saved', ['dest']), ('state', 'loaded', ['src'])] - module = AnsibleModule(argument_spec=argument_spec, required_if=required_if, supports_check_mode=False) - - if not HAS_PYVMOMI: - module.fail_json(msg='pyvmomi is required for this module') + module = AnsibleModule(argument_spec=argument_spec, + required_if=required_if, + supports_check_mode=False) vmware_cfg_backup = VMwareConfigurationBackup(module) vmware_cfg_backup.process_state()