1#!/usr/local/bin/python3.8
2# -*- coding: utf-8 -*-
3
4# Copyright: (c) 2016, IBM Corp
5# Author(s): Andreas Nafpliotis <nafpliot@de.ibm.com>
6#
7# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
8
9from __future__ import absolute_import, division, print_function
10__metaclass__ = type
11
12
13DOCUMENTATION = r'''
14---
15module: vmware_local_user_manager
16short_description: Manage local users on an ESXi host
17description:
18    - Manage local users on an ESXi host
19author:
20- Andreas Nafpliotis (@nafpliot-ibm)
21notes:
22    - Tested on ESXi 6.0
23    - Be sure that the ESXi user used for login, has the appropriate rights to create / delete / edit users
24requirements:
25    - "python >= 2.6"
26    - PyVmomi installed
27options:
28    local_user_name:
29        description:
30            - The local user name to be changed.
31        required: True
32        type: str
33    local_user_password:
34        description:
35            - The password to be set.
36        required: False
37        type: str
38    local_user_description:
39        description:
40            - Description for the user.
41        required: False
42        type: str
43    state:
44        description:
45            - Indicate desired state of the user. If the user already exists when C(state=present), the user info is updated
46        choices: ['present', 'absent']
47        default: present
48        type: str
49extends_documentation_fragment:
50- community.vmware.vmware.documentation
51
52'''
53
54EXAMPLES = r'''
55- name: Add local user to ESXi
56  community.vmware.vmware_local_user_manager:
57    hostname: esxi_hostname
58    username: root
59    password: vmware
60    local_user_name: foo
61    local_user_password: password
62  delegate_to: localhost
63'''
64
65RETURN = r'''# '''
66
67try:
68    from pyVmomi import vim, vmodl
69except ImportError:
70    pass
71
72from ansible.module_utils.basic import AnsibleModule
73from ansible_collections.community.vmware.plugins.module_utils.vmware import PyVmomi, vmware_argument_spec
74
75
76class VMwareLocalUserManager(PyVmomi):
77
78    def __init__(self, module):
79        super(VMwareLocalUserManager, self).__init__(module)
80        self.local_user_name = self.module.params['local_user_name']
81        self.local_user_password = self.module.params['local_user_password']
82        self.local_user_description = self.module.params['local_user_description']
83        self.state = self.module.params['state']
84
85        if self.is_vcenter():
86            self.module.fail_json(msg="Failed to get local account manager settings "
87                                      "from ESXi server: %s" % self.module.params['hostname'],
88                                  details="It seems that %s is a vCenter server instead of an "
89                                          "ESXi server" % self.module.params['hostname'])
90
91    def process_state(self):
92        try:
93            local_account_manager_states = {
94                'absent': {
95                    'present': self.state_remove_user,
96                    'absent': self.state_exit_unchanged,
97                },
98                'present': {
99                    'present': self.state_update_user,
100                    'absent': self.state_create_user,
101                }
102            }
103
104            local_account_manager_states[self.state][self.check_local_user_manager_state()]()
105        except vmodl.RuntimeFault as runtime_fault:
106            self.module.fail_json(msg=runtime_fault.msg)
107        except vmodl.MethodFault as method_fault:
108            self.module.fail_json(msg=method_fault.msg)
109        except Exception as e:
110            self.module.fail_json(msg=str(e))
111
112    def check_local_user_manager_state(self):
113        user_account = self.find_user_account()
114        if not user_account:
115            return 'absent'
116        else:
117            return 'present'
118
119    def find_user_account(self):
120        searchStr = self.local_user_name
121        exactMatch = True
122        findUsers = True
123        findGroups = False
124        user_account = self.content.userDirectory.RetrieveUserGroups(None, searchStr, None, None, exactMatch, findUsers, findGroups)
125        return user_account
126
127    def create_account_spec(self):
128        account_spec = vim.host.LocalAccountManager.AccountSpecification()
129        account_spec.id = self.local_user_name
130        account_spec.password = self.local_user_password
131        account_spec.description = self.local_user_description
132        return account_spec
133
134    def state_create_user(self):
135        account_spec = self.create_account_spec()
136
137        try:
138            self.content.accountManager.CreateUser(account_spec)
139            self.module.exit_json(changed=True)
140        except vmodl.RuntimeFault as runtime_fault:
141            self.module.fail_json(msg=runtime_fault.msg)
142        except vmodl.MethodFault as method_fault:
143            self.module.fail_json(msg=method_fault.msg)
144
145    def state_update_user(self):
146        account_spec = self.create_account_spec()
147
148        try:
149            self.content.accountManager.UpdateUser(account_spec)
150            self.module.exit_json(changed=True)
151        except vmodl.RuntimeFault as runtime_fault:
152            self.module.fail_json(msg=runtime_fault.msg)
153        except vmodl.MethodFault as method_fault:
154            self.module.fail_json(msg=method_fault.msg)
155
156    def state_remove_user(self):
157        try:
158            self.content.accountManager.RemoveUser(self.local_user_name)
159            self.module.exit_json(changed=True)
160        except vmodl.RuntimeFault as runtime_fault:
161            self.module.fail_json(msg=runtime_fault.msg)
162        except vmodl.MethodFault as method_fault:
163            self.module.fail_json(msg=method_fault.msg)
164
165    def state_exit_unchanged(self):
166        self.module.exit_json(changed=False)
167
168
169def main():
170    argument_spec = vmware_argument_spec()
171    argument_spec.update(dict(local_user_name=dict(required=True, type='str'),
172                              local_user_password=dict(type='str', no_log=True),
173                              local_user_description=dict(type='str'),
174                              state=dict(default='present', choices=['present', 'absent'], type='str')))
175
176    module = AnsibleModule(argument_spec=argument_spec,
177                           required_if=[
178                               ['state', 'present', ['local_user_password']]
179                           ],
180                           supports_check_mode=False)
181
182    vmware_local_user_manager = VMwareLocalUserManager(module)
183    vmware_local_user_manager.process_state()
184
185
186if __name__ == '__main__':
187    main()
188