From a5eea9042ecfeeeaebc5a673344984a9cad21fa9 Mon Sep 17 00:00:00 2001 From: Dag Wieers Date: Mon, 24 Jul 2017 19:02:58 +0200 Subject: [PATCH] vmware_host: Small fixes and docs updates (#25144) * vmware_host: Small fixes and docs updates This PR includes: - A fix to no longer require a datacenter folder for adding a host - Documentation improvements - Ensure imports are specific * Update vmware_host Fix adds following: * Update logic in vmware_host * Update example documentation * Added test case for vmware_host Signed-off-by: Abhijeet Kasurde --- .../modules/cloud/vmware/vmware_host.py | 136 ++++++++++-------- test/integration/targets/vmware_host/aliases | 2 + .../targets/vmware_host/tasks/main.yml | 124 ++++++++++++++++ 3 files changed, 201 insertions(+), 61 deletions(-) create mode 100644 test/integration/targets/vmware_host/aliases create mode 100644 test/integration/targets/vmware_host/tasks/main.yml diff --git a/lib/ansible/modules/cloud/vmware/vmware_host.py b/lib/ansible/modules/cloud/vmware/vmware_host.py index cf6f1cc9ad9..8cd4d174da2 100644 --- a/lib/ansible/modules/cloud/vmware/vmware_host.py +++ b/lib/ansible/modules/cloud/vmware/vmware_host.py @@ -22,67 +22,66 @@ ANSIBLE_METADATA = {'metadata_version': '1.0', 'status': ['preview'], 'supported_by': 'community'} - -DOCUMENTATION = ''' +DOCUMENTATION = r''' --- module: vmware_host short_description: Add/remove ESXi host to/from vCenter description: - - This module can be used to add/remove an ESXi host to/from vCenter -version_added: 2.0 -author: "Joseph Callen (@jcpowermac), Russell Teague (@mtnbikenc)" +- This module can be used to add/remove an ESXi host to/from vCenter. +version_added: '2.0' +author: +- Joseph Callen (@jcpowermac) +- Russell Teague (@mtnbikenc) notes: - - Tested on vSphere 5.5 +- Tested on vSphere 5.5 requirements: - - "python >= 2.6" - - PyVmomi +- python >= 2.6 +- PyVmomi options: - datacenter_name: - description: - - Name of the datacenter to add the host - required: True - cluster_name: - description: - - Name of the cluster to add the host - required: True - esxi_hostname: - description: - - ESXi hostname to manage - required: True - esxi_username: - description: - - ESXi username - required: True - esxi_password: - description: - - ESXi password - required: True - state: - description: - - Add or remove the host - default: 'present' - choices: - - 'present' - - 'absent' - required: False + datacenter_name: + description: + - Name of the datacenter to add the host. + required: yes + cluster_name: + description: + - Name of the cluster to add the host. + required: yes + esxi_hostname: + description: + - ESXi hostname to manage. + required: yes + esxi_username: + description: + - ESXi username. + required: yes + esxi_password: + description: + - ESXi password. + required: yes + state: + description: + - Add or remove the host. + choices: [absent, present] + default: present extends_documentation_fragment: vmware.documentation ''' -EXAMPLES = ''' -# Example from Ansible playbook +EXAMPLES = r''' +- name: Add ESXi Host to vCenter + vmware_host: + hostname: '{{ vcenter_hostname }}' + username: '{{ vcenter_username }}' + password: '{{ vcenter_password }}' + datacenter_name: datacenter_name + cluster_name: cluster_name + esxi_hostname: '{{ esxi_hostname }}' + esxi_username: '{{ esxi_username }}' + esxi_password: '{{ esxi_password }}' + state: present + delegate_to: localhost +''' - - name: Add ESXi Host to VCSA - local_action: - module: vmware_host - hostname: vcsa_host - username: vcsa_user - password: vcsa_pass - datacenter_name: datacenter_name - cluster_name: cluster_name - esxi_hostname: esxi_hostname - esxi_username: esxi_username - esxi_password: esxi_password - state: present +RETURN = r''' ''' try: @@ -91,6 +90,16 @@ try: except ImportError: HAS_PYVMOMI = False +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.vmware import ( + TaskError, + connect_to_api, + find_cluster_by_name, + find_datacenter_by_name, + vmware_argument_spec, + wait_for_task, +) + class VMwareHost(object): def __init__(self, module): @@ -131,7 +140,10 @@ class VMwareHost(object): def find_host_by_cluster_datacenter(self): self.dc = find_datacenter_by_name(self.content, self.datacenter_name) - self.cluster = find_cluster_by_name_datacenter(self.dc, self.cluster_name) + self.cluster = find_cluster_by_name(self.content, self.cluster_name, self.dc) + + if self.cluster is None: + self.module.fail_json(msg="Unable to find cluster %(cluster_name)s" % self.module.params) for host in self.cluster.host: if host.name == self.esxi_hostname: @@ -208,14 +220,19 @@ class VMwareHost(object): def main(): argument_spec = vmware_argument_spec() - argument_spec.update(dict(datacenter_name=dict(required=True, type='str'), - cluster_name=dict(required=True, type='str'), - esxi_hostname=dict(required=True, type='str'), - esxi_username=dict(required=True, type='str'), - esxi_password=dict(required=True, type='str', no_log=True), - state=dict(default='present', choices=['present', 'absent'], type='str'))) + argument_spec.update( + datacenter_name=dict(type='str', required=True), + cluster_name=dict(type='str'), + esxi_hostname=dict(type='str', required=True), + esxi_username=dict(type='str', required=True), + esxi_password=dict(type='str', required=True, no_log=True), + state=dict(type='str', default='present', choices=['absent', 'present']) + ) - module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + ) if not HAS_PYVMOMI: module.fail_json(msg='pyvmomi is required for this module') @@ -223,8 +240,5 @@ def main(): vmware_host = VMwareHost(module) vmware_host.process_state() -from ansible.module_utils.vmware import * -from ansible.module_utils.basic import * - if __name__ == '__main__': main() diff --git a/test/integration/targets/vmware_host/aliases b/test/integration/targets/vmware_host/aliases new file mode 100644 index 00000000000..1c56b8da49a --- /dev/null +++ b/test/integration/targets/vmware_host/aliases @@ -0,0 +1,2 @@ +posix/ci/cloud/vcenter +cloud/vcenter diff --git a/test/integration/targets/vmware_host/tasks/main.yml b/test/integration/targets/vmware_host/tasks/main.yml new file mode 100644 index 00000000000..db8456d5baa --- /dev/null +++ b/test/integration/targets/vmware_host/tasks/main.yml @@ -0,0 +1,124 @@ +# Test code for the vmware_host module. +# (c) 2017, Abhijeet Kasurde + +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# 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 . + +- name: make sure pyvmomi is installed + pip: + name: pyvmomi + state: latest + +- name: store the vcenter container ip + set_fact: + vcsim: "{{ lookup('env', 'vcenter_host') }}" + +- debug: var=vcsim + +- name: Wait for Flask controller to come up online + wait_for: + host: "{{ vcsim }}" + port: 5000 + state: started + +- name: kill vcsim + uri: + url: http://{{ vcsim }}:5000/killall + +- name: start vcsim + uri: + url: http://{{ vcsim }}:5000/spawn?cluster=2 + register: vcsim_instance + +- debug: + var: vcsim_instance + +- name: Wait for vcsim server to come up online + wait_for: + host: "{{ vcsim }}" + port: 443 + state: started + +- name: get a list of Datacenter from vcsim + uri: + url: http://{{ vcsim }}:5000/govc_find?filter=DC + register: datacenters + +- name: get a datacenter + set_fact: + dc1: "{{ datacenters.json[0] | basename }}" + +- debug: var=dc1 + + +- name: get a list of Cluster from vcsim + uri: + url: http://{{ vcsim }}:5000/govc_find?filter=CCR + register: clusters + +- name: get a cluster + set_fact: + ccr1: "{{ clusters.json[0] | basename }}" + +- debug: var=ccr1 + +# Testcase 0001: Add Host +- name: add host + vmware_host: + hostname: "{{ vcsim }}" + username: "{{ vcsim_instance.json.username }}" + password: "{{ vcsim_instance.json.password }}" + validate_certs: no + esxi_hostname: test_host_system_0001 + esxi_username: "{{ vcsim_instance.json.username }}" + esxi_password: "{{ vcsim_instance.json.password }}" + datacenter_name: "{{ dc1 }}" + cluster_name: "{{ ccr1 }}" + state: present + register: host_system_result_0001 + +- name: get a list of host system from vcsim after adding host system + uri: + url: http://{{ vcsim }}:5000/govc_find?filter=H + register: new_host_list + +- set_fact: + new_host: "{% for host in new_host_list.json %} {{ True if (host | basename) == 'test_host_system_0001' else False }} {% endfor %}" + +- name: ensure host system is present + assert: + that: + - host_system_result_0001.changed == true + - "'True' in new_host" + +# Testcase 0002: Add Host again +- name: add host again + vmware_host: + hostname: "{{ vcsim }}" + username: "{{ vcsim_instance.json.username }}" + password: "{{ vcsim_instance.json.password }}" + validate_certs: no + esxi_hostname: test_host_system_0001 + esxi_username: "{{ vcsim_instance.json.username }}" + esxi_password: "{{ vcsim_instance.json.password }}" + datacenter_name: "{{ dc1 }}" + cluster_name: "{{ ccr1 }}" + state: present + register: host_system_result_0002 + +- name: ensure host system is present + assert: + that: + - host_system_result_0002.changed == false