From 87119348b5dceae8dc49757a83294107ea787cb9 Mon Sep 17 00:00:00 2001 From: Abhijeet Kasurde Date: Fri, 30 Mar 2018 03:35:44 +0530 Subject: [PATCH] VMware: Use environment variable for connection (#37726) (#37745) This fix adds environment variables for connection in vmware_* modules. Signed-off-by: Abhijeet Kasurde (cherry picked from commit 0ae7a0e88c2aa161814d5fbea584170a4548c819) --- lib/ansible/module_utils/vmware.py | 44 +++++- .../utils/module_docs_fragments/vmware.py | 70 +++++---- .../tasks/create_d1_c1_f0_env.yml | 137 ++++++++++++++++++ 3 files changed, 207 insertions(+), 44 deletions(-) create mode 100644 test/integration/targets/vmware_guest/tasks/create_d1_c1_f0_env.yml diff --git a/lib/ansible/module_utils/vmware.py b/lib/ansible/module_utils/vmware.py index 2913fe28d5c..a76c219a0f5 100644 --- a/lib/ansible/module_utils/vmware.py +++ b/lib/ansible/module_utils/vmware.py @@ -34,6 +34,7 @@ except ImportError: from ansible.module_utils._text import to_text from ansible.module_utils.urls import fetch_url from ansible.module_utils.six import integer_types, iteritems, string_types +from ansible.module_utils.basic import env_fallback class TaskError(Exception): @@ -432,13 +433,27 @@ def list_snapshots(vm): def vmware_argument_spec(): - return dict( - hostname=dict(type='str', required=True), - username=dict(type='str', aliases=['user', 'admin'], required=True), - password=dict(type='str', aliases=['pass', 'pwd'], required=True, no_log=True), - port=dict(type='int', default=443), - validate_certs=dict(type='bool', required=False, default=True), + hostname=dict(type='str', + required=False, + fallback=(env_fallback, ['VMWARE_HOST']), + ), + username=dict(type='str', + aliases=['user', 'admin'], + required=False, + fallback=(env_fallback, ['VMWARE_USER'])), + password=dict(type='str', + aliases=['pass', 'pwd'], + required=False, + no_log=True, + fallback=(env_fallback, ['VMWARE_PASSWORD'])), + port=dict(type='int', + default=443, + fallback=(env_fallback, ['VMWARE_PORT'])), + validate_certs=dict(type='bool', + required=False, + default=True, + fallback=(env_fallback, ['VMWARE_VALIDATE_CERTS'])), ) @@ -446,9 +461,24 @@ def connect_to_api(module, disconnect_atexit=True): hostname = module.params['hostname'] username = module.params['username'] password = module.params['password'] - port = module.params['port'] or 443 + port = module.params.get('port', 443) validate_certs = module.params['validate_certs'] + if not hostname: + module.fail_json(msg="Hostname parameter is missing." + " Please specify this parameter in task or" + " export environment variable like 'export VMWARE_HOST=ESXI_HOSTNAME'") + + if not username: + module.fail_json(msg="Username parameter is missing." + " Please specify this parameter in task or" + " export environment variable like 'export VMWARE_USER=ESXI_USERNAME'") + + if not password: + module.fail_json(msg="Password parameter is missing." + " Please specify this parameter in task or" + " export environment variable like 'export VMWARE_PASSWORD=ESXI_PASSWORD'") + if validate_certs and not hasattr(ssl, 'SSLContext'): module.fail_json(msg='pyVim does not support changing verification mode with python < 2.7.9. Either update ' 'python or use validate_certs=false.') diff --git a/lib/ansible/utils/module_docs_fragments/vmware.py b/lib/ansible/utils/module_docs_fragments/vmware.py index 2752285db88..432f8cc14da 100644 --- a/lib/ansible/utils/module_docs_fragments/vmware.py +++ b/lib/ansible/utils/module_docs_fragments/vmware.py @@ -1,19 +1,6 @@ -# (c) 2016, Charles Paul -# -# 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 . +# Copyright: (c) 2016, Charles Paul +# Copyright: (c) 2018, Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) class ModuleDocFragment(object): @@ -21,29 +8,38 @@ class ModuleDocFragment(object): DOCUMENTATION = ''' options: hostname: - description: - - The hostname or IP address of the vSphere vCenter. - required: True + description: + - The hostname or IP address of the vSphere vCenter. + - If the value is not specified in the task, the value of environment variable C(VMWARE_HOST) will be used instead. + - Environment variable supported added in version 2.6. + required: False username: - description: - - The username of the vSphere vCenter. - required: True - aliases: ['user', 'admin'] + description: + - The username of the vSphere vCenter. + - If the value is not specified in the task, the value of environment variable C(VMWARE_USER) will be used instead. + - Environment variable supported added in version 2.6. + required: False + aliases: ['user', 'admin'] password: - description: - - The password of the vSphere vCenter. - required: True - aliases: ['pass', 'pwd'] + description: + - The password of the vSphere vCenter. + - If the value is not specified in the task, the value of environment variable C(VMWARE_PASSWORD) will be used instead. + - Environment variable supported added in version 2.6. + required: False + aliases: ['pass', 'pwd'] validate_certs: - description: - - Allows connection when SSL certificates are not valid. Set to - false when certificates are not trusted. - default: 'True' - type: bool + description: + - Allows connection when SSL certificates are not valid. Set to C(false) when certificates are not trusted. + - If the value is not specified in the task, the value of environment variable C(VMWARE_VALIDATE_CERTS) will be used instead. + - Environment variable supported added in version 2.6. + default: 'True' + type: bool port: - description: - - The port number of the vSphere vCenter or ESXi server. - required: False - default: 443 - version_added: 2.5 + description: + - The port number of the vSphere vCenter or ESXi server. + - If the value is not specified in the task, the value of environment variable C(VMWARE_PORT) will be used instead. + - Environment variable supported added in version 2.6. + required: False + default: 443 + version_added: 2.5 ''' diff --git a/test/integration/targets/vmware_guest/tasks/create_d1_c1_f0_env.yml b/test/integration/targets/vmware_guest/tasks/create_d1_c1_f0_env.yml new file mode 100644 index 00000000000..0c6bc03353d --- /dev/null +++ b/test/integration/targets/vmware_guest/tasks/create_d1_c1_f0_env.yml @@ -0,0 +1,137 @@ +# Test code for the vmware_guest module. +# Copyright: (c) 2018 Abhijeet Kasurde +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +- 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 with no folders + uri: + url: http://{{ vcsim }}:5000/spawn?datacenter=1&cluster=1&folder=0 + register: vcsim_instance + +- name: Wait for Flask controller to come up online + wait_for: + host: "{{ vcsim }}" + port: 443 + state: started + +- name: get a list of VMS from vcsim + uri: + url: http://{{ vcsim }}:5000/govc_find?filter=VM + register: vmlist + +- debug: var=vcsim_instance +- debug: var=vmlist + + +- name: create new VMs without connection parameters + vmware_guest: + name: "{{ 'newvm_' + item|basename }}" + guest_id: centos64Guest + datacenter: "{{ (item|basename).split('_')[0] }}" + hardware: + num_cpus: 4 + memory_mb: 512 + disk: + - size: 1gb + type: thin + autoselect_datastore: True + state: poweredoff + folder: "{{ item|dirname }}" + with_items: "{{ vmlist['json'] }}" + register: clone_d1_c1_f0_env + ignore_errors: True +- debug: var=clone_d1_c1_f0_env + +- name: assert that changes were not made + assert: + that: + - "clone_d1_c1_f0_env.results|map(attribute='changed')|unique|list == [False]" + +- name: create new VMs using only hostname environment variable + vmware_guest: + name: "{{ 'newvm_' + item|basename }}" + guest_id: centos64Guest + datacenter: "{{ (item|basename).split('_')[0] }}" + hardware: + num_cpus: 4 + memory_mb: 512 + disk: + - size: 1gb + type: thin + autoselect_datastore: True + state: poweredoff + folder: "{{ item|dirname }}" + with_items: "{{ vmlist['json'] }}" + register: clone_d1_c1_f0_env + ignore_errors: True + environment: + VMWARE_HOST: "{{ vcsim }}" +- debug: var=clone_d1_c1_f0_env + +- name: assert that changes were made + assert: + that: + - "clone_d1_c1_f0_env.results|map(attribute='changed')|unique|list == [False]" + +- name: create new VMs using hostname and username environment variable + vmware_guest: + name: "{{ 'newvm_' + item|basename }}" + guest_id: centos64Guest + datacenter: "{{ (item|basename).split('_')[0] }}" + hardware: + num_cpus: 4 + memory_mb: 512 + disk: + - size: 1gb + type: thin + autoselect_datastore: True + state: poweredoff + folder: "{{ item|dirname }}" + with_items: "{{ vmlist['json'] }}" + register: clone_d1_c1_f0_env + ignore_errors: True + environment: + VMWARE_HOST: "{{ vcsim }}" + VMWARE_USER: "{{ vcsim_instance['json']['username'] }}" +- debug: var=clone_d1_c1_f0_env + +- name: assert that changes were not made + assert: + that: + - "clone_d1_c1_f0_env.results|map(attribute='changed')|unique|list == [False]" + +- name: create new VMs using all environment variables + vmware_guest: + name: "{{ 'newvm_' + item|basename }}" + guest_id: centos64Guest + datacenter: "{{ (item|basename).split('_')[0] }}" + hardware: + num_cpus: 4 + memory_mb: 512 + disk: + - size: 1gb + type: thin + autoselect_datastore: True + state: poweredoff + folder: "{{ item|dirname }}" + with_items: "{{ vmlist['json'] }}" + register: clone_d1_c1_f0_env + environment: + VMWARE_HOST: "{{ vcsim }}" + VMWARE_USER: "{{ vcsim_instance['json']['username'] }}" + VMWARE_PASSWORD: "{{ vcsim_instance['json']['password'] }}" + VMWARE_VALIDATE_CERTS: False +- debug: var=clone_d1_c1_f0_env + +- name: assert that changes were made + assert: + that: + - "clone_d1_c1_f0_env.results|map(attribute='changed')|unique|list == [True]"