Skip to content

Commit

Permalink
VMware: check for ESXi server while creating user (ansible#33061)
Browse files Browse the repository at this point in the history
This fix check for ESXi server instance before proceeding
with managing local user. Also, adds integration tests for
this change.

Fixes: ansible#32465

Signed-off-by: Abhijeet Kasurde <[email protected]>
  • Loading branch information
Akasurde authored Dec 15, 2017
1 parent 3151025 commit 29d3505
Show file tree
Hide file tree
Showing 10 changed files with 183 additions and 24 deletions.
18 changes: 18 additions & 0 deletions lib/ansible/module_utils/vmware.py
Original file line number Diff line number Diff line change
Expand Up @@ -808,6 +808,24 @@ def __init__(self, module):
self.current_vm_obj = None
self.content = connect_to_api(self.module)

def is_vcenter(self):
"""
Check if given hostname is vCenter or ESXi host
Returns: True if given connection is with vCenter server
False if given connection is with ESXi server
"""
api_type = None
try:
api_type = self.content.about.apiType
except (vmodl.RuntimeFault, vim.fault.VimFault) as exc:
self.module.fail_json(msg="Failed to get status of vCenter server : %s" % exc.msg)

if api_type == 'VirtualCenter':
return True
elif api_type == 'HostAgent':
return False

# Virtual Machine related functions
def get_vm(self):
vm = None
Expand Down
5 changes: 5 additions & 0 deletions lib/ansible/modules/cloud/vmware/vmware_guest.py
Original file line number Diff line number Diff line change
Expand Up @@ -1233,6 +1233,11 @@ def obj_has_parent(self, obj, parent):
if current_parent.name == parent.name:
return True

# Check if we have reached till root folder
moid = current_parent._moId
if moid in ['group-d1', 'ha-folder-root']:
return False

current_parent = current_parent.parent
if current_parent is None:
return False
Expand Down
41 changes: 22 additions & 19 deletions lib/ansible/modules/cloud/vmware/vmware_local_user_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@
__metaclass__ = type


ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
ANSIBLE_METADATA = {
'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'
}


DOCUMENTATION = '''
Expand All @@ -32,15 +34,15 @@
options:
local_user_name:
description:
- The local user name to be changed
- The local user name to be changed.
required: True
local_user_password:
description:
- The password to be set
- The password to be set.
required: False
local_user_description:
description:
- Description for the user
- Description for the user.
required: False
state:
description:
Expand All @@ -65,24 +67,28 @@

try:
from pyVmomi import vim, vmodl
HAS_PYVMOMI = True
except ImportError:
HAS_PYVMOMI = False
pass

from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.vmware import HAS_PYVMOMI, connect_to_api, vmware_argument_spec
from ansible.module_utils.vmware import PyVmomi, vmware_argument_spec


class VMwareLocalUserManager(object):
class VMwareLocalUserManager(PyVmomi):

def __init__(self, module):
self.module = module
self.content = connect_to_api(self.module)
super(VMwareLocalUserManager, self).__init__(module)
self.local_user_name = self.module.params['local_user_name']
self.local_user_password = self.module.params['local_user_password']
self.local_user_description = self.module.params['local_user_description']
self.state = self.module.params['state']

if self.is_vcenter():
self.module.fail_json(msg="Failed to get local account manager settings "
"from ESXi server: %s" % self.module.params['hostname'],
details="It seems that %s is a vCenter server instead of an "
"ESXi server" % self.module.params['hostname'])

def process_state(self):
try:
local_account_manager_states = {
Expand Down Expand Up @@ -162,17 +168,14 @@ def state_exit_unchanged(self):


def main():

argument_spec = vmware_argument_spec()
argument_spec.update(dict(local_user_name=dict(required=True, type='str'),
local_user_password=dict(required=False, type='str', no_log=True),
local_user_description=dict(required=False, type='str'),
local_user_password=dict(type='str', no_log=True),
local_user_description=dict(type='str'),
state=dict(default='present', choices=['present', 'absent'], type='str')))

module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=False)

if not HAS_PYVMOMI:
module.fail_json(msg='pyvmomi is required for this module')
module = AnsibleModule(argument_spec=argument_spec,
supports_check_mode=False)

vmware_local_user_manager = VMwareLocalUserManager(module)
vmware_local_user_manager.process_state()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,4 @@
- name: make sure no changes were made
assert:
that:
- "poweroff_d1_c1_f0.results|map(attribute='changed')|unique|list == [False]"
- "poweroff_d1_c1_f0.results|map(attribute='changed')|unique|list == [True]"
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,4 @@
- name: make sure no changes were made
assert:
that:
- "poweroff_d1_c1_f1.results|map(attribute='changed')|unique|list == [False]"
- "poweroff_d1_c1_f1.results|map(attribute='changed')|unique|list == [True]"
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,4 @@
- name: make sure no changes were made
assert:
that:
- "poweroff_d1_c1_f0.results|map(attribute='changed')|unique|list == [False]"
- "poweroff_d1_c1_f0.results|map(attribute='changed')|unique|list == [True]"
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,4 @@
- name: make sure no changes were made
assert:
that:
- "poweroff_d1_c1_f1.results|map(attribute='changed')|unique|list == [False]"
- "poweroff_d1_c1_f1.results|map(attribute='changed')|unique|list == [True]"
3 changes: 3 additions & 0 deletions test/integration/targets/vmware_local_user_manager/aliases
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
posix/ci/cloud/group1/vcenter
cloud/vcenter
destructive
130 changes: 130 additions & 0 deletions test/integration/targets/vmware_local_user_manager/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
# Test code for the vmware_local_user_manager module.
# Copyright: (c) 2017, Abhijeet Kasurde <[email protected]>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)

- name: make sure pyvmomi is installed
pip:
name: pyvmomi
state: latest
when: "{{ ansible_user_id == 'root' }}"

- 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

# Local user manager works only with standalone ESXi server
- name: start vcsim
uri:
url: http://{{ vcsim }}:5000/spawn?esx=1
register: vcsim_instance

- debug:
var: vcsim_instance

- name: Wait for vcsim server to come up online
wait_for:
host: "{{ vcsim }}"
port: 443
state: started

# Testcase 0001: Add Local user in ESXi server
- name: add local user
vmware_local_user_manager:
hostname: "{{ vcsim }}"
username: "{{ vcsim_instance.json.username }}"
password: "{{ vcsim_instance.json.password }}"
validate_certs: no
local_user_name: testuser_0001
local_user_password: "SamplePassword!"
state: present
register: user_add_0001

- name: ensure user is created
assert:
that:
- user_add_0001.changed == true

# Testcase 0002: Delete Local user in ESXi server
#- name: Delete local user
# vmware_local_user_manager:
# hostname: "{{ vcsim }}"
# username: "{{ vcsim_instance.json.username }}"
# password: "{{ vcsim_instance.json.password }}"
# validate_certs: no
# local_user_name: testuser_0001
# state: absent
# register: user_delete_0002

#- name: ensure user is deleted
# assert:
# that:
# - user_delete_0002.changed == true

#- name: kill vcsim
# uri:
# url: http://{{ vcsim }}:5000/killall

# Local user manager works only with standalone ESXi server not with vCenter
# So testcase should check failures
#- 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

# Testcase 0003: Add Local user in vCenter server
#- name: add local user
# vmware_local_user_manager:
# hostname: "{{ vcsim }}"
# username: "{{ vcsim_instance.json.username }}"
# password: "{{ vcsim_instance.json.password }}"
# validate_certs: no
# local_user_name: testuser_0003
# local_user_password: "SamplePassword!"
# state: present
# register: user_add_0003
# ignore_errors: yes

#- name: ensure user is created
# assert:
# that:
# - user_add_0003.changed == false
# - "{{ 'Failed to get local account manager settings' in user_add_0003.msg }}"

## Testcase 0003: Delete Local user in vCenter server
#- name: Delete local user
# vmware_local_user_manager:
# hostname: "{{ vcsim }}"
# username: "{{ vcsim_instance.json.username }}"
# password: "{{ vcsim_instance.json.password }}"
# validate_certs: no
# local_user_name: testuser_0003
# state: absent
# register: user_delete_0004
# ignore_errors: yes

#- name: ensure user is deleted
# assert:
# that:
# - user_delete_0004.changed == false
# - "{{ 'Failed to get local account manager settings' in user_delete_0004.msg }}"
2 changes: 1 addition & 1 deletion test/runner/lib/cloud/vcenter.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def __init__(self, args):
if os.environ.get('ANSIBLE_VCSIM_CONTAINER'):
self.image = os.environ.get('ANSIBLE_VCSIM_CONTAINER')
else:
self.image = 'ansible/ansible:vcenter-simulator@sha256:7b7cd213219dc09ae528a8e226804e662c2fae0c1d7d7e2ee3aa9e9c08d4059a'
self.image = 'ansible/ansible:vcenter-simulator@sha256:005faa7442cd164b2a6087b069227fe1979068f420366cc49c57625bcf8f6ebe'
self.container_name = ''

def filter(self, targets, exclude):
Expand Down

0 comments on commit 29d3505

Please sign in to comment.